LCOV - code coverage report
Current view: | top level - Modules - _elementtree.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 81 | 1902 | 4.3 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 6 | 122 | 4.9 %
|  |  | Branches: | 76 | 1450 | 5.2 %

               Branch data     Line data    Source code
           1                 :            : /*--------------------------------------------------------------------
           2                 :            :  * Licensed to PSF under a Contributor Agreement.
           3                 :            :  * See https://www.python.org/psf/license for licensing details.
           4                 :            :  *
           5                 :            :  * _elementtree - C accelerator for xml.etree.ElementTree
           6                 :            :  * Copyright (c) 1999-2009 by Secret Labs AB.  All rights reserved.
           7                 :            :  * Copyright (c) 1999-2009 by Fredrik Lundh.
           8                 :            :  *
           9                 :            :  * info@pythonware.com
          10                 :            :  * http://www.pythonware.com
          11                 :            :  *--------------------------------------------------------------------
          12                 :            :  */
          13                 :            :
          14                 :            : #define PY_SSIZE_T_CLEAN
          15                 :            :
          16                 :            : #include "Python.h"
          17                 :            : #include "structmember.h"         // PyMemberDef
          18                 :            :
          19                 :            : /* -------------------------------------------------------------------- */
          20                 :            : /* configuration */
          21                 :            :
          22                 :            : /* An element can hold this many children without extra memory
          23                 :            :    allocations. */
          24                 :            : #define STATIC_CHILDREN 4
          25                 :            :
          26                 :            : /* For best performance, chose a value so that 80-90% of all nodes
          27                 :            :    have no more than the given number of children.  Set this to zero
          28                 :            :    to minimize the size of the element structure itself (this only
          29                 :            :    helps if you have lots of leaf nodes with attributes). */
          30                 :            :
          31                 :            : /* Also note that pymalloc always allocates blocks in multiples of
          32                 :            :    eight bytes.  For the current C version of ElementTree, this means
          33                 :            :    that the number of children should be an even number, at least on
          34                 :            :    32-bit platforms. */
          35                 :            :
          36                 :            : /* -------------------------------------------------------------------- */
          37                 :            :
          38                 :            : /* compiler tweaks */
          39                 :            : #if defined(_MSC_VER)
          40                 :            : #define LOCAL(type) static __inline type __fastcall
          41                 :            : #else
          42                 :            : #define LOCAL(type) static type
          43                 :            : #endif
          44                 :            :
          45                 :            : /* macros used to store 'join' flags in string object pointers.  note
          46                 :            :    that all use of text and tail as object pointers must be wrapped in
          47                 :            :    JOIN_OBJ.  see comments in the ElementObject definition for more
          48                 :            :    info. */
          49                 :            : #define JOIN_GET(p) ((uintptr_t) (p) & 1)
          50                 :            : #define JOIN_SET(p, flag) ((void*) ((uintptr_t) (JOIN_OBJ(p)) | (flag)))
          51                 :            : #define JOIN_OBJ(p) ((PyObject*) ((uintptr_t) (p) & ~(uintptr_t)1))
          52                 :            :
          53                 :            : /* Py_SETREF for a PyObject* that uses a join flag. */
          54                 :            : Py_LOCAL_INLINE(void)
          55                 :          0 : _set_joined_ptr(PyObject **p, PyObject *new_joined_ptr)
          56                 :            : {
          57                 :          0 :     PyObject *tmp = JOIN_OBJ(*p);
          58                 :          0 :     *p = new_joined_ptr;
          59                 :          0 :     Py_DECREF(tmp);
          60                 :          0 : }
          61                 :            :
          62                 :            : /* Py_CLEAR for a PyObject* that uses a join flag. Pass the pointer by
          63                 :            :  * reference since this function sets it to NULL.
          64                 :            : */
          65                 :          0 : static void _clear_joined_ptr(PyObject **p)
          66                 :            : {
          67         [ #  # ]:          0 :     if (*p) {
          68                 :          0 :         _set_joined_ptr(p, NULL);
          69                 :            :     }
          70                 :          0 : }
          71                 :            :
          72                 :            : /* Per-module state; PEP 3121 */
          73                 :            : typedef struct {
          74                 :            :     PyObject *parseerror_obj;
          75                 :            :     PyObject *deepcopy_obj;
          76                 :            :     PyObject *elementpath_obj;
          77                 :            :     PyObject *comment_factory;
          78                 :            :     PyObject *pi_factory;
          79                 :            :     /* Interned strings */
          80                 :            :     PyObject *str_text;
          81                 :            :     PyObject *str_tail;
          82                 :            :     PyObject *str_append;
          83                 :            :     PyObject *str_find;
          84                 :            :     PyObject *str_findtext;
          85                 :            :     PyObject *str_findall;
          86                 :            :     PyObject *str_iterfind;
          87                 :            :     PyObject *str_doctype;
          88                 :            :     /* Types defined by this extension */
          89                 :            :     PyTypeObject *Element_Type;
          90                 :            :     PyTypeObject *ElementIter_Type;
          91                 :            :     PyTypeObject *TreeBuilder_Type;
          92                 :            :     PyTypeObject *XMLParser_Type;
          93                 :            : } elementtreestate;
          94                 :            :
          95                 :            : static struct PyModuleDef elementtreemodule;
          96                 :            :
          97                 :            : /* Given a module object (assumed to be _elementtree), get its per-module
          98                 :            :  * state.
          99                 :            :  */
         100                 :            : static inline elementtreestate*
         101                 :         11 : get_elementtree_state(PyObject *module)
         102                 :            : {
         103                 :         11 :     void *state = PyModule_GetState(module);
         104                 :            :     assert(state != NULL);
         105                 :         11 :     return (elementtreestate *)state;
         106                 :            : }
         107                 :            :
         108                 :            : static inline elementtreestate *
         109                 :          0 : get_elementtree_state_by_cls(PyTypeObject *cls)
         110                 :            : {
         111                 :          0 :     void *state = PyType_GetModuleState(cls);
         112                 :            :     assert(state != NULL);
         113                 :          0 :     return (elementtreestate *)state;
         114                 :            : }
         115                 :            :
         116                 :            : static inline elementtreestate *
         117                 :          0 : get_elementtree_state_by_type(PyTypeObject *tp)
         118                 :            : {
         119                 :          0 :     PyObject *mod = PyType_GetModuleByDef(tp, &elementtreemodule);
         120                 :            :     assert(mod != NULL);
         121                 :          0 :     return get_elementtree_state(mod);
         122                 :            : }
         123                 :            :
         124                 :            : static int
         125                 :          2 : elementtree_clear(PyObject *m)
         126                 :            : {
         127                 :          2 :     elementtreestate *st = get_elementtree_state(m);
         128         [ +  + ]:          2 :     Py_CLEAR(st->parseerror_obj);
         129         [ +  + ]:          2 :     Py_CLEAR(st->deepcopy_obj);
         130         [ +  + ]:          2 :     Py_CLEAR(st->elementpath_obj);
         131         [ -  + ]:          2 :     Py_CLEAR(st->comment_factory);
         132         [ -  + ]:          2 :     Py_CLEAR(st->pi_factory);
         133                 :            :
         134                 :            :     // Interned strings
         135         [ +  + ]:          2 :     Py_CLEAR(st->str_append);
         136         [ +  + ]:          2 :     Py_CLEAR(st->str_find);
         137         [ +  + ]:          2 :     Py_CLEAR(st->str_findall);
         138         [ +  + ]:          2 :     Py_CLEAR(st->str_findtext);
         139         [ +  + ]:          2 :     Py_CLEAR(st->str_iterfind);
         140         [ +  + ]:          2 :     Py_CLEAR(st->str_tail);
         141         [ +  + ]:          2 :     Py_CLEAR(st->str_text);
         142         [ +  + ]:          2 :     Py_CLEAR(st->str_doctype);
         143                 :            :
         144                 :            :     // Heap types
         145         [ +  + ]:          2 :     Py_CLEAR(st->Element_Type);
         146         [ +  + ]:          2 :     Py_CLEAR(st->ElementIter_Type);
         147         [ +  + ]:          2 :     Py_CLEAR(st->TreeBuilder_Type);
         148         [ +  + ]:          2 :     Py_CLEAR(st->XMLParser_Type);
         149                 :          2 :     return 0;
         150                 :            : }
         151                 :            :
         152                 :            : static int
         153                 :          8 : elementtree_traverse(PyObject *m, visitproc visit, void *arg)
         154                 :            : {
         155                 :          8 :     elementtreestate *st = get_elementtree_state(m);
         156   [ +  -  -  + ]:          8 :     Py_VISIT(st->parseerror_obj);
         157   [ +  -  -  + ]:          8 :     Py_VISIT(st->deepcopy_obj);
         158   [ +  -  -  + ]:          8 :     Py_VISIT(st->elementpath_obj);
         159   [ -  +  -  - ]:          8 :     Py_VISIT(st->comment_factory);
         160   [ -  +  -  - ]:          8 :     Py_VISIT(st->pi_factory);
         161                 :            :
         162                 :            :     // Heap types
         163   [ +  -  -  + ]:          8 :     Py_VISIT(st->Element_Type);
         164   [ +  -  -  + ]:          8 :     Py_VISIT(st->ElementIter_Type);
         165   [ +  -  -  + ]:          8 :     Py_VISIT(st->TreeBuilder_Type);
         166   [ +  -  -  + ]:          8 :     Py_VISIT(st->XMLParser_Type);
         167                 :          8 :     return 0;
         168                 :            : }
         169                 :            :
         170                 :            : static void
         171                 :          1 : elementtree_free(void *m)
         172                 :            : {
         173                 :          1 :     elementtree_clear((PyObject *)m);
         174                 :          1 : }
         175                 :            :
         176                 :            : /* helpers */
         177                 :            :
         178                 :            : LOCAL(PyObject*)
         179                 :          0 : list_join(PyObject* list)
         180                 :            : {
         181                 :            :     /* join list elements */
         182                 :            :     PyObject* joiner;
         183                 :            :     PyObject* result;
         184                 :            :
         185                 :          0 :     joiner = PyUnicode_FromStringAndSize("", 0);
         186         [ #  # ]:          0 :     if (!joiner)
         187                 :          0 :         return NULL;
         188                 :          0 :     result = PyUnicode_Join(joiner, list);
         189                 :          0 :     Py_DECREF(joiner);
         190                 :          0 :     return result;
         191                 :            : }
         192                 :            :
         193                 :            : /* Is the given object an empty dictionary?
         194                 :            : */
         195                 :            : static int
         196                 :          0 : is_empty_dict(PyObject *obj)
         197                 :            : {
         198   [ #  #  #  # ]:          0 :     return PyDict_CheckExact(obj) && PyDict_GET_SIZE(obj) == 0;
         199                 :            : }
         200                 :            :
         201                 :            :
         202                 :            : /* -------------------------------------------------------------------- */
         203                 :            : /* the Element type */
         204                 :            :
         205                 :            : typedef struct {
         206                 :            :
         207                 :            :     /* attributes (a dictionary object), or NULL if no attributes */
         208                 :            :     PyObject* attrib;
         209                 :            :
         210                 :            :     /* child elements */
         211                 :            :     Py_ssize_t length; /* actual number of items */
         212                 :            :     Py_ssize_t allocated; /* allocated items */
         213                 :            :
         214                 :            :     /* this either points to _children or to a malloced buffer */
         215                 :            :     PyObject* *children;
         216                 :            :
         217                 :            :     PyObject* _children[STATIC_CHILDREN];
         218                 :            :
         219                 :            : } ElementObjectExtra;
         220                 :            :
         221                 :            : typedef struct {
         222                 :            :     PyObject_HEAD
         223                 :            :
         224                 :            :     /* element tag (a string). */
         225                 :            :     PyObject* tag;
         226                 :            :
         227                 :            :     /* text before first child.  note that this is a tagged pointer;
         228                 :            :        use JOIN_OBJ to get the object pointer.  the join flag is used
         229                 :            :        to distinguish lists created by the tree builder from lists
         230                 :            :        assigned to the attribute by application code; the former
         231                 :            :        should be joined before being returned to the user, the latter
         232                 :            :        should be left intact. */
         233                 :            :     PyObject* text;
         234                 :            :
         235                 :            :     /* text after this element, in parent.  note that this is a tagged
         236                 :            :        pointer; use JOIN_OBJ to get the object pointer. */
         237                 :            :     PyObject* tail;
         238                 :            :
         239                 :            :     ElementObjectExtra* extra;
         240                 :            :
         241                 :            :     PyObject *weakreflist; /* For tp_weaklistoffset */
         242                 :            :
         243                 :            : } ElementObject;
         244                 :            :
         245                 :            :
         246                 :            : #define Element_CheckExact(st, op) Py_IS_TYPE(op, (st)->Element_Type)
         247                 :            : #define Element_Check(st, op) PyObject_TypeCheck(op, (st)->Element_Type)
         248                 :            :
         249                 :            :
         250                 :            : /* -------------------------------------------------------------------- */
         251                 :            : /* Element constructors and destructor */
         252                 :            :
         253                 :            : LOCAL(int)
         254                 :          0 : create_extra(ElementObject* self, PyObject* attrib)
         255                 :            : {
         256                 :          0 :     self->extra = PyObject_Malloc(sizeof(ElementObjectExtra));
         257         [ #  # ]:          0 :     if (!self->extra) {
         258                 :          0 :         PyErr_NoMemory();
         259                 :          0 :         return -1;
         260                 :            :     }
         261                 :            :
         262                 :          0 :     self->extra->attrib = Py_XNewRef(attrib);
         263                 :            :
         264                 :          0 :     self->extra->length = 0;
         265                 :          0 :     self->extra->allocated = STATIC_CHILDREN;
         266                 :          0 :     self->extra->children = self->extra->_children;
         267                 :            :
         268                 :          0 :     return 0;
         269                 :            : }
         270                 :            :
         271                 :            : LOCAL(void)
         272                 :          0 : dealloc_extra(ElementObjectExtra *extra)
         273                 :            : {
         274                 :            :     Py_ssize_t i;
         275                 :            :
         276         [ #  # ]:          0 :     if (!extra)
         277                 :          0 :         return;
         278                 :            :
         279                 :          0 :     Py_XDECREF(extra->attrib);
         280                 :            :
         281         [ #  # ]:          0 :     for (i = 0; i < extra->length; i++)
         282                 :          0 :         Py_DECREF(extra->children[i]);
         283                 :            :
         284         [ #  # ]:          0 :     if (extra->children != extra->_children)
         285                 :          0 :         PyObject_Free(extra->children);
         286                 :            :
         287                 :          0 :     PyObject_Free(extra);
         288                 :            : }
         289                 :            :
         290                 :            : LOCAL(void)
         291                 :          0 : clear_extra(ElementObject* self)
         292                 :            : {
         293                 :            :     ElementObjectExtra *myextra;
         294                 :            :
         295         [ #  # ]:          0 :     if (!self->extra)
         296                 :          0 :         return;
         297                 :            :
         298                 :            :     /* Avoid DECREFs calling into this code again (cycles, etc.)
         299                 :            :     */
         300                 :          0 :     myextra = self->extra;
         301                 :          0 :     self->extra = NULL;
         302                 :            :
         303                 :          0 :     dealloc_extra(myextra);
         304                 :            : }
         305                 :            :
         306                 :            : /* Convenience internal function to create new Element objects with the given
         307                 :            :  * tag and attributes.
         308                 :            : */
         309                 :            : LOCAL(PyObject*)
         310                 :          0 : create_new_element(elementtreestate *st, PyObject *tag, PyObject *attrib)
         311                 :            : {
         312                 :            :     ElementObject* self;
         313                 :            :
         314                 :          0 :     self = PyObject_GC_New(ElementObject, st->Element_Type);
         315         [ #  # ]:          0 :     if (self == NULL)
         316                 :          0 :         return NULL;
         317                 :          0 :     self->extra = NULL;
         318                 :          0 :     self->tag = Py_NewRef(tag);
         319                 :          0 :     self->text = Py_NewRef(Py_None);
         320                 :          0 :     self->tail = Py_NewRef(Py_None);
         321                 :          0 :     self->weakreflist = NULL;
         322                 :            :
         323                 :          0 :     PyObject_GC_Track(self);
         324                 :            :
         325   [ #  #  #  # ]:          0 :     if (attrib != NULL && !is_empty_dict(attrib)) {
         326         [ #  # ]:          0 :         if (create_extra(self, attrib) < 0) {
         327                 :          0 :             Py_DECREF(self);
         328                 :          0 :             return NULL;
         329                 :            :         }
         330                 :            :     }
         331                 :            :
         332                 :          0 :     return (PyObject*) self;
         333                 :            : }
         334                 :            :
         335                 :            : static PyObject *
         336                 :          0 : element_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         337                 :            : {
         338                 :          0 :     ElementObject *e = (ElementObject *)type->tp_alloc(type, 0);
         339         [ #  # ]:          0 :     if (e != NULL) {
         340                 :          0 :         e->tag = Py_NewRef(Py_None);
         341                 :          0 :         e->text = Py_NewRef(Py_None);
         342                 :          0 :         e->tail = Py_NewRef(Py_None);
         343                 :          0 :         e->extra = NULL;
         344                 :          0 :         e->weakreflist = NULL;
         345                 :            :     }
         346                 :          0 :     return (PyObject *)e;
         347                 :            : }
         348                 :            :
         349                 :            : /* Helper function for extracting the attrib dictionary from a keywords dict.
         350                 :            :  * This is required by some constructors/functions in this module that can
         351                 :            :  * either accept attrib as a keyword argument or all attributes splashed
         352                 :            :  * directly into *kwds.
         353                 :            :  *
         354                 :            :  * Return a dictionary with the content of kwds merged into the content of
         355                 :            :  * attrib. If there is no attrib keyword, return a copy of kwds.
         356                 :            :  */
         357                 :            : static PyObject*
         358                 :          0 : get_attrib_from_keywords(PyObject *kwds)
         359                 :            : {
         360                 :          0 :     PyObject *attrib_str = PyUnicode_FromString("attrib");
         361         [ #  # ]:          0 :     if (attrib_str == NULL) {
         362                 :          0 :         return NULL;
         363                 :            :     }
         364                 :          0 :     PyObject *attrib = PyDict_GetItemWithError(kwds, attrib_str);
         365                 :            :
         366         [ #  # ]:          0 :     if (attrib) {
         367                 :            :         /* If attrib was found in kwds, copy its value and remove it from
         368                 :            :          * kwds
         369                 :            :          */
         370         [ #  # ]:          0 :         if (!PyDict_Check(attrib)) {
         371                 :          0 :             Py_DECREF(attrib_str);
         372                 :          0 :             PyErr_Format(PyExc_TypeError, "attrib must be dict, not %.100s",
         373                 :          0 :                          Py_TYPE(attrib)->tp_name);
         374                 :          0 :             return NULL;
         375                 :            :         }
         376                 :          0 :         attrib = PyDict_Copy(attrib);
         377   [ #  #  #  # ]:          0 :         if (attrib && PyDict_DelItem(kwds, attrib_str) < 0) {
         378                 :          0 :             Py_SETREF(attrib, NULL);
         379                 :            :         }
         380                 :            :     }
         381         [ #  # ]:          0 :     else if (!PyErr_Occurred()) {
         382                 :          0 :         attrib = PyDict_New();
         383                 :            :     }
         384                 :            :
         385                 :          0 :     Py_DECREF(attrib_str);
         386                 :            :
         387   [ #  #  #  # ]:          0 :     if (attrib != NULL && PyDict_Update(attrib, kwds) < 0) {
         388                 :          0 :         Py_DECREF(attrib);
         389                 :          0 :         return NULL;
         390                 :            :     }
         391                 :          0 :     return attrib;
         392                 :            : }
         393                 :            :
         394                 :            : /*[clinic input]
         395                 :            : module _elementtree
         396                 :            : class _elementtree.Element "ElementObject *" "clinic_state()->Element_Type"
         397                 :            : class _elementtree.TreeBuilder "TreeBuilderObject *" "clinic_state()->TreeBuilder_Type"
         398                 :            : class _elementtree.XMLParser "XMLParserObject *" "clinic_state()->XMLParser_Type"
         399                 :            : [clinic start generated code]*/
         400                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=6c83ea832d2b0ef1]*/
         401                 :            :
         402                 :            : static int
         403                 :          0 : element_init(PyObject *self, PyObject *args, PyObject *kwds)
         404                 :            : {
         405                 :            :     PyObject *tag;
         406                 :          0 :     PyObject *attrib = NULL;
         407                 :            :     ElementObject *self_elem;
         408                 :            :
         409         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "O|O!:Element", &tag, &PyDict_Type, &attrib))
         410                 :          0 :         return -1;
         411                 :            :
         412         [ #  # ]:          0 :     if (attrib) {
         413                 :            :         /* attrib passed as positional arg */
         414                 :          0 :         attrib = PyDict_Copy(attrib);
         415         [ #  # ]:          0 :         if (!attrib)
         416                 :          0 :             return -1;
         417         [ #  # ]:          0 :         if (kwds) {
         418         [ #  # ]:          0 :             if (PyDict_Update(attrib, kwds) < 0) {
         419                 :          0 :                 Py_DECREF(attrib);
         420                 :          0 :                 return -1;
         421                 :            :             }
         422                 :            :         }
         423         [ #  # ]:          0 :     } else if (kwds) {
         424                 :            :         /* have keywords args */
         425                 :          0 :         attrib = get_attrib_from_keywords(kwds);
         426         [ #  # ]:          0 :         if (!attrib)
         427                 :          0 :             return -1;
         428                 :            :     }
         429                 :            :
         430                 :          0 :     self_elem = (ElementObject *)self;
         431                 :            :
         432   [ #  #  #  # ]:          0 :     if (attrib != NULL && !is_empty_dict(attrib)) {
         433         [ #  # ]:          0 :         if (create_extra(self_elem, attrib) < 0) {
         434                 :          0 :             Py_DECREF(attrib);
         435                 :          0 :             return -1;
         436                 :            :         }
         437                 :            :     }
         438                 :            :
         439                 :            :     /* We own a reference to attrib here and it's no longer needed. */
         440                 :          0 :     Py_XDECREF(attrib);
         441                 :            :
         442                 :            :     /* Replace the objects already pointed to by tag, text and tail. */
         443                 :          0 :     Py_XSETREF(self_elem->tag, Py_NewRef(tag));
         444                 :            :
         445                 :          0 :     _set_joined_ptr(&self_elem->text, Py_NewRef(Py_None));
         446                 :          0 :     _set_joined_ptr(&self_elem->tail, Py_NewRef(Py_None));
         447                 :            :
         448                 :          0 :     return 0;
         449                 :            : }
         450                 :            :
         451                 :            : LOCAL(int)
         452                 :          0 : element_resize(ElementObject* self, Py_ssize_t extra)
         453                 :            : {
         454                 :            :     Py_ssize_t size;
         455                 :            :     PyObject* *children;
         456                 :            :
         457                 :            :     assert(extra >= 0);
         458                 :            :     /* make sure self->children can hold the given number of extra
         459                 :            :        elements.  set an exception and return -1 if allocation failed */
         460                 :            :
         461         [ #  # ]:          0 :     if (!self->extra) {
         462         [ #  # ]:          0 :         if (create_extra(self, NULL) < 0)
         463                 :          0 :             return -1;
         464                 :            :     }
         465                 :            :
         466                 :          0 :     size = self->extra->length + extra;  /* never overflows */
         467                 :            :
         468         [ #  # ]:          0 :     if (size > self->extra->allocated) {
         469                 :            :         /* use Python 2.4's list growth strategy */
         470         [ #  # ]:          0 :         size = (size >> 3) + (size < 9 ? 3 : 6) + size;
         471                 :            :         /* Coverity CID #182 size_error: Allocating 1 bytes to pointer "children"
         472                 :            :          * which needs at least 4 bytes.
         473                 :            :          * Although it's a false alarm always assume at least one child to
         474                 :            :          * be safe.
         475                 :            :          */
         476         [ #  # ]:          0 :         size = size ? size : 1;
         477         [ #  # ]:          0 :         if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*))
         478                 :          0 :             goto nomemory;
         479         [ #  # ]:          0 :         if (self->extra->children != self->extra->_children) {
         480                 :            :             /* Coverity CID #182 size_error: Allocating 1 bytes to pointer
         481                 :            :              * "children", which needs at least 4 bytes. Although it's a
         482                 :            :              * false alarm always assume at least one child to be safe.
         483                 :            :              */
         484                 :          0 :             children = PyObject_Realloc(self->extra->children,
         485                 :            :                                         size * sizeof(PyObject*));
         486         [ #  # ]:          0 :             if (!children)
         487                 :          0 :                 goto nomemory;
         488                 :            :         } else {
         489                 :          0 :             children = PyObject_Malloc(size * sizeof(PyObject*));
         490         [ #  # ]:          0 :             if (!children)
         491                 :          0 :                 goto nomemory;
         492                 :            :             /* copy existing children from static area to malloc buffer */
         493                 :          0 :             memcpy(children, self->extra->children,
         494                 :          0 :                    self->extra->length * sizeof(PyObject*));
         495                 :            :         }
         496                 :          0 :         self->extra->children = children;
         497                 :          0 :         self->extra->allocated = size;
         498                 :            :     }
         499                 :            :
         500                 :          0 :     return 0;
         501                 :            :
         502                 :          0 :   nomemory:
         503                 :          0 :     PyErr_NoMemory();
         504                 :          0 :     return -1;
         505                 :            : }
         506                 :            :
         507                 :            : LOCAL(void)
         508                 :          0 : raise_type_error(PyObject *element)
         509                 :            : {
         510                 :          0 :     PyErr_Format(PyExc_TypeError,
         511                 :            :                  "expected an Element, not \"%.200s\"",
         512                 :          0 :                  Py_TYPE(element)->tp_name);
         513                 :          0 : }
         514                 :            :
         515                 :            : LOCAL(int)
         516                 :          0 : element_add_subelement(elementtreestate *st, ElementObject *self,
         517                 :            :                        PyObject *element)
         518                 :            : {
         519                 :            :     /* add a child element to a parent */
         520         [ #  # ]:          0 :     if (!Element_Check(st, element)) {
         521                 :          0 :         raise_type_error(element);
         522                 :          0 :         return -1;
         523                 :            :     }
         524                 :            :
         525         [ #  # ]:          0 :     if (element_resize(self, 1) < 0)
         526                 :          0 :         return -1;
         527                 :            :
         528                 :          0 :     self->extra->children[self->extra->length] = Py_NewRef(element);
         529                 :            :
         530                 :          0 :     self->extra->length++;
         531                 :            :
         532                 :          0 :     return 0;
         533                 :            : }
         534                 :            :
         535                 :            : LOCAL(PyObject*)
         536                 :          0 : element_get_attrib(ElementObject* self)
         537                 :            : {
         538                 :            :     /* return borrowed reference to attrib dictionary */
         539                 :            :     /* note: this function assumes that the extra section exists */
         540                 :            :
         541                 :          0 :     PyObject* res = self->extra->attrib;
         542                 :            :
         543         [ #  # ]:          0 :     if (!res) {
         544                 :            :         /* create missing dictionary */
         545                 :          0 :         res = self->extra->attrib = PyDict_New();
         546                 :            :     }
         547                 :            :
         548                 :          0 :     return res;
         549                 :            : }
         550                 :            :
         551                 :            : LOCAL(PyObject*)
         552                 :          0 : element_get_text(ElementObject* self)
         553                 :            : {
         554                 :            :     /* return borrowed reference to text attribute */
         555                 :            :
         556                 :          0 :     PyObject *res = self->text;
         557                 :            :
         558         [ #  # ]:          0 :     if (JOIN_GET(res)) {
         559                 :          0 :         res = JOIN_OBJ(res);
         560         [ #  # ]:          0 :         if (PyList_CheckExact(res)) {
         561                 :          0 :             PyObject *tmp = list_join(res);
         562         [ #  # ]:          0 :             if (!tmp)
         563                 :          0 :                 return NULL;
         564                 :          0 :             self->text = tmp;
         565                 :          0 :             Py_SETREF(res, tmp);
         566                 :            :         }
         567                 :            :     }
         568                 :            :
         569                 :          0 :     return res;
         570                 :            : }
         571                 :            :
         572                 :            : LOCAL(PyObject*)
         573                 :          0 : element_get_tail(ElementObject* self)
         574                 :            : {
         575                 :            :     /* return borrowed reference to text attribute */
         576                 :            :
         577                 :          0 :     PyObject *res = self->tail;
         578                 :            :
         579         [ #  # ]:          0 :     if (JOIN_GET(res)) {
         580                 :          0 :         res = JOIN_OBJ(res);
         581         [ #  # ]:          0 :         if (PyList_CheckExact(res)) {
         582                 :          0 :             PyObject *tmp = list_join(res);
         583         [ #  # ]:          0 :             if (!tmp)
         584                 :          0 :                 return NULL;
         585                 :          0 :             self->tail = tmp;
         586                 :          0 :             Py_SETREF(res, tmp);
         587                 :            :         }
         588                 :            :     }
         589                 :            :
         590                 :          0 :     return res;
         591                 :            : }
         592                 :            :
         593                 :            : static PyObject*
         594                 :          0 : subelement(PyObject *self, PyObject *args, PyObject *kwds)
         595                 :            : {
         596                 :            :     PyObject* elem;
         597                 :            :
         598                 :          0 :     elementtreestate *st = get_elementtree_state(self);
         599                 :            :     ElementObject* parent;
         600                 :            :     PyObject* tag;
         601                 :          0 :     PyObject* attrib = NULL;
         602         [ #  # ]:          0 :     if (!PyArg_ParseTuple(args, "O!O|O!:SubElement",
         603                 :            :                           st->Element_Type, &parent, &tag,
         604                 :            :                           &PyDict_Type, &attrib)) {
         605                 :          0 :         return NULL;
         606                 :            :     }
         607                 :            :
         608         [ #  # ]:          0 :     if (attrib) {
         609                 :            :         /* attrib passed as positional arg */
         610                 :          0 :         attrib = PyDict_Copy(attrib);
         611         [ #  # ]:          0 :         if (!attrib)
         612                 :          0 :             return NULL;
         613   [ #  #  #  # ]:          0 :         if (kwds != NULL && PyDict_Update(attrib, kwds) < 0) {
         614                 :          0 :             Py_DECREF(attrib);
         615                 :          0 :             return NULL;
         616                 :            :         }
         617         [ #  # ]:          0 :     } else if (kwds) {
         618                 :            :         /* have keyword args */
         619                 :          0 :         attrib = get_attrib_from_keywords(kwds);
         620         [ #  # ]:          0 :         if (!attrib)
         621                 :          0 :             return NULL;
         622                 :            :     } else {
         623                 :            :         /* no attrib arg, no kwds, so no attribute */
         624                 :            :     }
         625                 :            :
         626                 :          0 :     elem = create_new_element(st, tag, attrib);
         627                 :          0 :     Py_XDECREF(attrib);
         628         [ #  # ]:          0 :     if (elem == NULL)
         629                 :          0 :         return NULL;
         630                 :            :
         631         [ #  # ]:          0 :     if (element_add_subelement(st, parent, elem) < 0) {
         632                 :          0 :         Py_DECREF(elem);
         633                 :          0 :         return NULL;
         634                 :            :     }
         635                 :            :
         636                 :          0 :     return elem;
         637                 :            : }
         638                 :            :
         639                 :            : static int
         640                 :          0 : element_gc_traverse(ElementObject *self, visitproc visit, void *arg)
         641                 :            : {
         642   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(self));
         643   [ #  #  #  # ]:          0 :     Py_VISIT(self->tag);
         644   [ #  #  #  # ]:          0 :     Py_VISIT(JOIN_OBJ(self->text));
         645   [ #  #  #  # ]:          0 :     Py_VISIT(JOIN_OBJ(self->tail));
         646                 :            :
         647         [ #  # ]:          0 :     if (self->extra) {
         648                 :            :         Py_ssize_t i;
         649   [ #  #  #  # ]:          0 :         Py_VISIT(self->extra->attrib);
         650                 :            :
         651         [ #  # ]:          0 :         for (i = 0; i < self->extra->length; ++i)
         652   [ #  #  #  # ]:          0 :             Py_VISIT(self->extra->children[i]);
         653                 :            :     }
         654                 :          0 :     return 0;
         655                 :            : }
         656                 :            :
         657                 :            : static int
         658                 :          0 : element_gc_clear(ElementObject *self)
         659                 :            : {
         660         [ #  # ]:          0 :     Py_CLEAR(self->tag);
         661                 :          0 :     _clear_joined_ptr(&self->text);
         662                 :          0 :     _clear_joined_ptr(&self->tail);
         663                 :            :
         664                 :            :     /* After dropping all references from extra, it's no longer valid anyway,
         665                 :            :      * so fully deallocate it.
         666                 :            :     */
         667                 :          0 :     clear_extra(self);
         668                 :          0 :     return 0;
         669                 :            : }
         670                 :            :
         671                 :            : static void
         672                 :          0 : element_dealloc(ElementObject* self)
         673                 :            : {
         674                 :          0 :     PyTypeObject *tp = Py_TYPE(self);
         675                 :            :
         676                 :            :     /* bpo-31095: UnTrack is needed before calling any callbacks */
         677                 :          0 :     PyObject_GC_UnTrack(self);
         678   [ #  #  #  # ]:          0 :     Py_TRASHCAN_BEGIN(self, element_dealloc)
         679                 :            :
         680         [ #  # ]:          0 :     if (self->weakreflist != NULL)
         681                 :          0 :         PyObject_ClearWeakRefs((PyObject *) self);
         682                 :            :
         683                 :            :     /* element_gc_clear clears all references and deallocates extra
         684                 :            :     */
         685                 :          0 :     element_gc_clear(self);
         686                 :            :
         687                 :          0 :     tp->tp_free((PyObject *)self);
         688                 :          0 :     Py_DECREF(tp);
         689         [ #  # ]:          0 :     Py_TRASHCAN_END
         690                 :          0 : }
         691                 :            :
         692                 :            : /* -------------------------------------------------------------------- */
         693                 :            :
         694                 :            : /*[clinic input]
         695                 :            : _elementtree.Element.append
         696                 :            :
         697                 :            :     cls: defining_class
         698                 :            :     subelement: object(subclass_of='clinic_state()->Element_Type')
         699                 :            :     /
         700                 :            :
         701                 :            : [clinic start generated code]*/
         702                 :            :
         703                 :            : static PyObject *
         704                 :          0 : _elementtree_Element_append_impl(ElementObject *self, PyTypeObject *cls,
         705                 :            :                                  PyObject *subelement)
         706                 :            : /*[clinic end generated code: output=d00923711ea317fc input=8baf92679f9717b8]*/
         707                 :            : {
         708                 :          0 :     elementtreestate *st = get_elementtree_state_by_cls(cls);
         709         [ #  # ]:          0 :     if (element_add_subelement(st, self, subelement) < 0)
         710                 :          0 :         return NULL;
         711                 :            :
         712                 :          0 :     Py_RETURN_NONE;
         713                 :            : }
         714                 :            :
         715                 :            : /*[clinic input]
         716                 :            : _elementtree.Element.clear
         717                 :            :
         718                 :            : [clinic start generated code]*/
         719                 :            :
         720                 :            : static PyObject *
         721                 :          0 : _elementtree_Element_clear_impl(ElementObject *self)
         722                 :            : /*[clinic end generated code: output=8bcd7a51f94cfff6 input=3c719ff94bf45dd6]*/
         723                 :            : {
         724                 :          0 :     clear_extra(self);
         725                 :            :
         726                 :          0 :     _set_joined_ptr(&self->text, Py_NewRef(Py_None));
         727                 :          0 :     _set_joined_ptr(&self->tail, Py_NewRef(Py_None));
         728                 :            :
         729                 :          0 :     Py_RETURN_NONE;
         730                 :            : }
         731                 :            :
         732                 :            : /*[clinic input]
         733                 :            : _elementtree.Element.__copy__
         734                 :            :
         735                 :            :     cls: defining_class
         736                 :            :     /
         737                 :            :
         738                 :            : [clinic start generated code]*/
         739                 :            :
         740                 :            : static PyObject *
         741                 :          0 : _elementtree_Element___copy___impl(ElementObject *self, PyTypeObject *cls)
         742                 :            : /*[clinic end generated code: output=da22894421ff2b36 input=91edb92d9f441213]*/
         743                 :            : {
         744                 :            :     Py_ssize_t i;
         745                 :            :     ElementObject* element;
         746                 :          0 :     elementtreestate *st = get_elementtree_state_by_cls(cls);
         747                 :            :
         748                 :          0 :     element = (ElementObject*) create_new_element(
         749         [ #  # ]:          0 :         st, self->tag, self->extra ? self->extra->attrib : NULL);
         750         [ #  # ]:          0 :     if (!element)
         751                 :          0 :         return NULL;
         752                 :            :
         753                 :          0 :     Py_INCREF(JOIN_OBJ(self->text));
         754                 :          0 :     _set_joined_ptr(&element->text, self->text);
         755                 :            :
         756                 :          0 :     Py_INCREF(JOIN_OBJ(self->tail));
         757                 :          0 :     _set_joined_ptr(&element->tail, self->tail);
         758                 :            :
         759                 :            :     assert(!element->extra || !element->extra->length);
         760         [ #  # ]:          0 :     if (self->extra) {
         761         [ #  # ]:          0 :         if (element_resize(element, self->extra->length) < 0) {
         762                 :          0 :             Py_DECREF(element);
         763                 :          0 :             return NULL;
         764                 :            :         }
         765                 :            :
         766         [ #  # ]:          0 :         for (i = 0; i < self->extra->length; i++) {
         767                 :          0 :             element->extra->children[i] = Py_NewRef(self->extra->children[i]);
         768                 :            :         }
         769                 :            :
         770                 :            :         assert(!element->extra->length);
         771                 :          0 :         element->extra->length = self->extra->length;
         772                 :            :     }
         773                 :            :
         774                 :          0 :     return (PyObject*) element;
         775                 :            : }
         776                 :            :
         777                 :            : /* Helper for a deep copy. */
         778                 :            : LOCAL(PyObject *) deepcopy(elementtreestate *, PyObject *, PyObject *);
         779                 :            :
         780                 :            : /*[clinic input]
         781                 :            : _elementtree.Element.__deepcopy__
         782                 :            :
         783                 :            :     memo: object(subclass_of="&PyDict_Type")
         784                 :            :     /
         785                 :            :
         786                 :            : [clinic start generated code]*/
         787                 :            :
         788                 :            : static PyObject *
         789                 :          0 : _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo)
         790                 :            : /*[clinic end generated code: output=eefc3df50465b642 input=a2d40348c0aade10]*/
         791                 :            : {
         792                 :            :     Py_ssize_t i;
         793                 :            :     ElementObject* element;
         794                 :            :     PyObject* tag;
         795                 :            :     PyObject* attrib;
         796                 :            :     PyObject* text;
         797                 :            :     PyObject* tail;
         798                 :            :     PyObject* id;
         799                 :            :
         800                 :          0 :     PyTypeObject *tp = Py_TYPE(self);
         801                 :          0 :     elementtreestate *st = get_elementtree_state_by_type(tp);
         802                 :          0 :     tag = deepcopy(st, self->tag, memo);
         803         [ #  # ]:          0 :     if (!tag)
         804                 :          0 :         return NULL;
         805                 :            :
         806   [ #  #  #  # ]:          0 :     if (self->extra && self->extra->attrib) {
         807                 :          0 :         attrib = deepcopy(st, self->extra->attrib, memo);
         808         [ #  # ]:          0 :         if (!attrib) {
         809                 :          0 :             Py_DECREF(tag);
         810                 :          0 :             return NULL;
         811                 :            :         }
         812                 :            :     } else {
         813                 :          0 :         attrib = NULL;
         814                 :            :     }
         815                 :            :
         816                 :          0 :     element = (ElementObject*) create_new_element(st, tag, attrib);
         817                 :            :
         818                 :          0 :     Py_DECREF(tag);
         819                 :          0 :     Py_XDECREF(attrib);
         820                 :            :
         821         [ #  # ]:          0 :     if (!element)
         822                 :          0 :         return NULL;
         823                 :            :
         824                 :          0 :     text = deepcopy(st, JOIN_OBJ(self->text), memo);
         825         [ #  # ]:          0 :     if (!text)
         826                 :          0 :         goto error;
         827                 :          0 :     _set_joined_ptr(&element->text, JOIN_SET(text, JOIN_GET(self->text)));
         828                 :            :
         829                 :          0 :     tail = deepcopy(st, JOIN_OBJ(self->tail), memo);
         830         [ #  # ]:          0 :     if (!tail)
         831                 :          0 :         goto error;
         832                 :          0 :     _set_joined_ptr(&element->tail, JOIN_SET(tail, JOIN_GET(self->tail)));
         833                 :            :
         834                 :            :     assert(!element->extra || !element->extra->length);
         835         [ #  # ]:          0 :     if (self->extra) {
         836         [ #  # ]:          0 :         if (element_resize(element, self->extra->length) < 0)
         837                 :          0 :             goto error;
         838                 :            :
         839         [ #  # ]:          0 :         for (i = 0; i < self->extra->length; i++) {
         840                 :          0 :             PyObject* child = deepcopy(st, self->extra->children[i], memo);
         841   [ #  #  #  # ]:          0 :             if (!child || !Element_Check(st, child)) {
         842         [ #  # ]:          0 :                 if (child) {
         843                 :          0 :                     raise_type_error(child);
         844                 :          0 :                     Py_DECREF(child);
         845                 :            :                 }
         846                 :          0 :                 element->extra->length = i;
         847                 :          0 :                 goto error;
         848                 :            :             }
         849                 :          0 :             element->extra->children[i] = child;
         850                 :            :         }
         851                 :            :
         852                 :            :         assert(!element->extra->length);
         853                 :          0 :         element->extra->length = self->extra->length;
         854                 :            :     }
         855                 :            :
         856                 :            :     /* add object to memo dictionary (so deepcopy won't visit it again) */
         857                 :          0 :     id = PyLong_FromSsize_t((uintptr_t) self);
         858         [ #  # ]:          0 :     if (!id)
         859                 :          0 :         goto error;
         860                 :            :
         861                 :          0 :     i = PyDict_SetItem(memo, id, (PyObject*) element);
         862                 :            :
         863                 :          0 :     Py_DECREF(id);
         864                 :            :
         865         [ #  # ]:          0 :     if (i < 0)
         866                 :          0 :         goto error;
         867                 :            :
         868                 :          0 :     return (PyObject*) element;
         869                 :            :
         870                 :          0 :   error:
         871                 :          0 :     Py_DECREF(element);
         872                 :          0 :     return NULL;
         873                 :            : }
         874                 :            :
         875                 :            : LOCAL(PyObject *)
         876                 :          0 : deepcopy(elementtreestate *st, PyObject *object, PyObject *memo)
         877                 :            : {
         878                 :            :     /* do a deep copy of the given object */
         879                 :            :     PyObject *stack[2];
         880                 :            :
         881                 :            :     /* Fast paths */
         882   [ #  #  #  # ]:          0 :     if (object == Py_None || PyUnicode_CheckExact(object)) {
         883                 :          0 :         return Py_NewRef(object);
         884                 :            :     }
         885                 :            :
         886         [ #  # ]:          0 :     if (Py_REFCNT(object) == 1) {
         887         [ #  # ]:          0 :         if (PyDict_CheckExact(object)) {
         888                 :            :             PyObject *key, *value;
         889                 :          0 :             Py_ssize_t pos = 0;
         890                 :          0 :             int simple = 1;
         891         [ #  # ]:          0 :             while (PyDict_Next(object, &pos, &key, &value)) {
         892   [ #  #  #  # ]:          0 :                 if (!PyUnicode_CheckExact(key) || !PyUnicode_CheckExact(value)) {
         893                 :          0 :                     simple = 0;
         894                 :          0 :                     break;
         895                 :            :                 }
         896                 :            :             }
         897         [ #  # ]:          0 :             if (simple)
         898                 :          0 :                 return PyDict_Copy(object);
         899                 :            :             /* Fall through to general case */
         900                 :            :         }
         901         [ #  # ]:          0 :         else if (Element_CheckExact(st, object)) {
         902                 :          0 :             return _elementtree_Element___deepcopy___impl(
         903                 :            :                 (ElementObject *)object, memo);
         904                 :            :         }
         905                 :            :     }
         906                 :            :
         907                 :            :     /* General case */
         908         [ #  # ]:          0 :     if (!st->deepcopy_obj) {
         909                 :          0 :         PyErr_SetString(PyExc_RuntimeError,
         910                 :            :                         "deepcopy helper not found");
         911                 :          0 :         return NULL;
         912                 :            :     }
         913                 :            :
         914                 :          0 :     stack[0] = object;
         915                 :          0 :     stack[1] = memo;
         916                 :          0 :     return _PyObject_FastCall(st->deepcopy_obj, stack, 2);
         917                 :            : }
         918                 :            :
         919                 :            :
         920                 :            : /*[clinic input]
         921                 :            : _elementtree.Element.__sizeof__ -> size_t
         922                 :            :
         923                 :            : [clinic start generated code]*/
         924                 :            :
         925                 :            : static size_t
         926                 :          0 : _elementtree_Element___sizeof___impl(ElementObject *self)
         927                 :            : /*[clinic end generated code: output=baae4e7ae9fe04ec input=54e298c501f3e0d0]*/
         928                 :            : {
         929                 :          0 :     size_t result = _PyObject_SIZE(Py_TYPE(self));
         930         [ #  # ]:          0 :     if (self->extra) {
         931                 :          0 :         result += sizeof(ElementObjectExtra);
         932         [ #  # ]:          0 :         if (self->extra->children != self->extra->_children) {
         933                 :          0 :             result += (size_t)self->extra->allocated * sizeof(PyObject*);
         934                 :            :         }
         935                 :            :     }
         936                 :          0 :     return result;
         937                 :            : }
         938                 :            :
         939                 :            : /* dict keys for getstate/setstate. */
         940                 :            : #define PICKLED_TAG "tag"
         941                 :            : #define PICKLED_CHILDREN "_children"
         942                 :            : #define PICKLED_ATTRIB "attrib"
         943                 :            : #define PICKLED_TAIL "tail"
         944                 :            : #define PICKLED_TEXT "text"
         945                 :            :
         946                 :            : /* __getstate__ returns a fabricated instance dict as in the pure-Python
         947                 :            :  * Element implementation, for interoperability/interchangeability.  This
         948                 :            :  * makes the pure-Python implementation details an API, but (a) there aren't
         949                 :            :  * any unnecessary structures there; and (b) it buys compatibility with 3.2
         950                 :            :  * pickles.  See issue #16076.
         951                 :            :  */
         952                 :            : /*[clinic input]
         953                 :            : _elementtree.Element.__getstate__
         954                 :            :
         955                 :            : [clinic start generated code]*/
         956                 :            :
         957                 :            : static PyObject *
         958                 :          0 : _elementtree_Element___getstate___impl(ElementObject *self)
         959                 :            : /*[clinic end generated code: output=37279aeeb6bb5b04 input=f0d16d7ec2f7adc1]*/
         960                 :            : {
         961                 :            :     Py_ssize_t i;
         962                 :            :     PyObject *children, *attrib;
         963                 :            :
         964                 :            :     /* Build a list of children. */
         965         [ #  # ]:          0 :     children = PyList_New(self->extra ? self->extra->length : 0);
         966         [ #  # ]:          0 :     if (!children)
         967                 :          0 :         return NULL;
         968         [ #  # ]:          0 :     for (i = 0; i < PyList_GET_SIZE(children); i++) {
         969                 :          0 :         PyObject *child = Py_NewRef(self->extra->children[i]);
         970                 :          0 :         PyList_SET_ITEM(children, i, child);
         971                 :            :     }
         972                 :            :
         973   [ #  #  #  # ]:          0 :     if (self->extra && self->extra->attrib) {
         974                 :          0 :         attrib = Py_NewRef(self->extra->attrib);
         975                 :            :     }
         976                 :            :     else {
         977                 :          0 :         attrib = PyDict_New();
         978         [ #  # ]:          0 :         if (!attrib) {
         979                 :          0 :             Py_DECREF(children);
         980                 :          0 :             return NULL;
         981                 :            :         }
         982                 :            :     }
         983                 :            :
         984                 :          0 :     return Py_BuildValue("{sOsNsNsOsO}",
         985                 :            :                          PICKLED_TAG, self->tag,
         986                 :            :                          PICKLED_CHILDREN, children,
         987                 :            :                          PICKLED_ATTRIB, attrib,
         988                 :          0 :                          PICKLED_TEXT, JOIN_OBJ(self->text),
         989                 :          0 :                          PICKLED_TAIL, JOIN_OBJ(self->tail));
         990                 :            : }
         991                 :            :
         992                 :            : static PyObject *
         993                 :          0 : element_setstate_from_attributes(elementtreestate *st,
         994                 :            :                                  ElementObject *self,
         995                 :            :                                  PyObject *tag,
         996                 :            :                                  PyObject *attrib,
         997                 :            :                                  PyObject *text,
         998                 :            :                                  PyObject *tail,
         999                 :            :                                  PyObject *children)
        1000                 :            : {
        1001                 :            :     Py_ssize_t i, nchildren;
        1002                 :          0 :     ElementObjectExtra *oldextra = NULL;
        1003                 :            :
        1004         [ #  # ]:          0 :     if (!tag) {
        1005                 :          0 :         PyErr_SetString(PyExc_TypeError, "tag may not be NULL");
        1006                 :          0 :         return NULL;
        1007                 :            :     }
        1008                 :            :
        1009                 :          0 :     Py_XSETREF(self->tag, Py_NewRef(tag));
        1010                 :            :
        1011         [ #  # ]:          0 :     text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None;
        1012                 :          0 :     Py_INCREF(JOIN_OBJ(text));
        1013                 :          0 :     _set_joined_ptr(&self->text, text);
        1014                 :            :
        1015         [ #  # ]:          0 :     tail = tail ? JOIN_SET(tail, PyList_CheckExact(tail)) : Py_None;
        1016                 :          0 :     Py_INCREF(JOIN_OBJ(tail));
        1017                 :          0 :     _set_joined_ptr(&self->tail, tail);
        1018                 :            :
        1019                 :            :     /* Handle ATTRIB and CHILDREN. */
        1020   [ #  #  #  # ]:          0 :     if (!children && !attrib) {
        1021                 :          0 :         Py_RETURN_NONE;
        1022                 :            :     }
        1023                 :            :
        1024                 :            :     /* Compute 'nchildren'. */
        1025         [ #  # ]:          0 :     if (children) {
        1026         [ #  # ]:          0 :         if (!PyList_Check(children)) {
        1027                 :          0 :             PyErr_SetString(PyExc_TypeError, "'_children' is not a list");
        1028                 :          0 :             return NULL;
        1029                 :            :         }
        1030                 :          0 :         nchildren = PyList_GET_SIZE(children);
        1031                 :            :
        1032                 :            :         /* (Re-)allocate 'extra'.
        1033                 :            :            Avoid DECREFs calling into this code again (cycles, etc.)
        1034                 :            :          */
        1035                 :          0 :         oldextra = self->extra;
        1036                 :          0 :         self->extra = NULL;
        1037         [ #  # ]:          0 :         if (element_resize(self, nchildren)) {
        1038                 :            :             assert(!self->extra || !self->extra->length);
        1039                 :          0 :             clear_extra(self);
        1040                 :          0 :             self->extra = oldextra;
        1041                 :          0 :             return NULL;
        1042                 :            :         }
        1043                 :            :         assert(self->extra);
        1044                 :            :         assert(self->extra->allocated >= nchildren);
        1045         [ #  # ]:          0 :         if (oldextra) {
        1046                 :            :             assert(self->extra->attrib == NULL);
        1047                 :          0 :             self->extra->attrib = oldextra->attrib;
        1048                 :          0 :             oldextra->attrib = NULL;
        1049                 :            :         }
        1050                 :            :
        1051                 :            :         /* Copy children */
        1052         [ #  # ]:          0 :         for (i = 0; i < nchildren; i++) {
        1053                 :          0 :             PyObject *child = PyList_GET_ITEM(children, i);
        1054         [ #  # ]:          0 :             if (!Element_Check(st, child)) {
        1055                 :          0 :                 raise_type_error(child);
        1056                 :          0 :                 self->extra->length = i;
        1057                 :          0 :                 dealloc_extra(oldextra);
        1058                 :          0 :                 return NULL;
        1059                 :            :             }
        1060                 :          0 :             self->extra->children[i] = Py_NewRef(child);
        1061                 :            :         }
        1062                 :            :
        1063                 :            :         assert(!self->extra->length);
        1064                 :          0 :         self->extra->length = nchildren;
        1065                 :            :     }
        1066                 :            :     else {
        1067         [ #  # ]:          0 :         if (element_resize(self, 0)) {
        1068                 :          0 :             return NULL;
        1069                 :            :         }
        1070                 :            :     }
        1071                 :            :
        1072                 :            :     /* Stash attrib. */
        1073                 :          0 :     Py_XSETREF(self->extra->attrib, Py_XNewRef(attrib));
        1074                 :          0 :     dealloc_extra(oldextra);
        1075                 :            :
        1076                 :          0 :     Py_RETURN_NONE;
        1077                 :            : }
        1078                 :            :
        1079                 :            : /* __setstate__ for Element instance from the Python implementation.
        1080                 :            :  * 'state' should be the instance dict.
        1081                 :            :  */
        1082                 :            :
        1083                 :            : static PyObject *
        1084                 :          0 : element_setstate_from_Python(elementtreestate *st, ElementObject *self,
        1085                 :            :                              PyObject *state)
        1086                 :            : {
        1087                 :            :     static char *kwlist[] = {PICKLED_TAG, PICKLED_ATTRIB, PICKLED_TEXT,
        1088                 :            :                              PICKLED_TAIL, PICKLED_CHILDREN, 0};
        1089                 :            :     PyObject *args;
        1090                 :            :     PyObject *tag, *attrib, *text, *tail, *children;
        1091                 :            :     PyObject *retval;
        1092                 :            :
        1093                 :          0 :     tag = attrib = text = tail = children = NULL;
        1094                 :          0 :     args = PyTuple_New(0);
        1095         [ #  # ]:          0 :     if (!args)
        1096                 :          0 :         return NULL;
        1097                 :            :
        1098         [ #  # ]:          0 :     if (PyArg_ParseTupleAndKeywords(args, state, "|$OOOOO", kwlist, &tag,
        1099                 :            :                                     &attrib, &text, &tail, &children))
        1100                 :          0 :         retval = element_setstate_from_attributes(st, self, tag, attrib, text,
        1101                 :            :                                                   tail, children);
        1102                 :            :     else
        1103                 :          0 :         retval = NULL;
        1104                 :            :
        1105                 :          0 :     Py_DECREF(args);
        1106                 :          0 :     return retval;
        1107                 :            : }
        1108                 :            :
        1109                 :            : /*[clinic input]
        1110                 :            : _elementtree.Element.__setstate__
        1111                 :            :
        1112                 :            :     cls: defining_class
        1113                 :            :     state: object
        1114                 :            :     /
        1115                 :            :
        1116                 :            : [clinic start generated code]*/
        1117                 :            :
        1118                 :            : static PyObject *
        1119                 :          0 : _elementtree_Element___setstate___impl(ElementObject *self,
        1120                 :            :                                        PyTypeObject *cls, PyObject *state)
        1121                 :            : /*[clinic end generated code: output=598bfb5730f71509 input=13830488d35d51f7]*/
        1122                 :            : {
        1123         [ #  # ]:          0 :     if (!PyDict_CheckExact(state)) {
        1124                 :          0 :         PyErr_Format(PyExc_TypeError,
        1125                 :            :                      "Don't know how to unpickle \"%.200R\" as an Element",
        1126                 :            :                      state);
        1127                 :          0 :         return NULL;
        1128                 :            :     }
        1129                 :            :     else {
        1130                 :          0 :         elementtreestate *st = get_elementtree_state_by_cls(cls);
        1131                 :          0 :         return element_setstate_from_Python(st, self, state);
        1132                 :            :     }
        1133                 :            : }
        1134                 :            :
        1135                 :            : LOCAL(int)
        1136                 :          0 : checkpath(PyObject* tag)
        1137                 :            : {
        1138                 :            :     Py_ssize_t i;
        1139                 :          0 :     int check = 1;
        1140                 :            :
        1141                 :            :     /* check if a tag contains an xpath character */
        1142                 :            :
        1143                 :            : #define PATHCHAR(ch) \
        1144                 :            :     (ch == '/' || ch == '*' || ch == '[' || ch == '@' || ch == '.')
        1145                 :            :
        1146         [ #  # ]:          0 :     if (PyUnicode_Check(tag)) {
        1147                 :          0 :         const Py_ssize_t len = PyUnicode_GET_LENGTH(tag);
        1148                 :          0 :         const void *data = PyUnicode_DATA(tag);
        1149                 :          0 :         int kind = PyUnicode_KIND(tag);
        1150   [ #  #  #  #  :          0 :         if (len >= 3 && PyUnicode_READ(kind, data, 0) == '{' && (
                       #  # ]
        1151         [ #  # ]:          0 :                 PyUnicode_READ(kind, data, 1) == '}' || (
        1152         [ #  # ]:          0 :                 PyUnicode_READ(kind, data, 1) == '*' &&
        1153                 :          0 :                 PyUnicode_READ(kind, data, 2) == '}'))) {
        1154                 :            :             /* wildcard: '{}tag' or '{*}tag' */
        1155                 :          0 :             return 1;
        1156                 :            :         }
        1157         [ #  # ]:          0 :         for (i = 0; i < len; i++) {
        1158                 :          0 :             Py_UCS4 ch = PyUnicode_READ(kind, data, i);
        1159         [ #  # ]:          0 :             if (ch == '{')
        1160                 :          0 :                 check = 0;
        1161         [ #  # ]:          0 :             else if (ch == '}')
        1162                 :          0 :                 check = 1;
        1163   [ #  #  #  #  :          0 :             else if (check && PATHCHAR(ch))
              #  #  #  #  #
                    #  #  # ]
        1164                 :          0 :                 return 1;
        1165                 :            :         }
        1166                 :          0 :         return 0;
        1167                 :            :     }
        1168         [ #  # ]:          0 :     if (PyBytes_Check(tag)) {
        1169                 :          0 :         const char *p = PyBytes_AS_STRING(tag);
        1170                 :          0 :         const Py_ssize_t len = PyBytes_GET_SIZE(tag);
        1171   [ #  #  #  # ]:          0 :         if (len >= 3 && p[0] == '{' && (
        1172   [ #  #  #  #  :          0 :                 p[1] == '}' || (p[1] == '*' && p[2] == '}'))) {
                       #  # ]
        1173                 :            :             /* wildcard: '{}tag' or '{*}tag' */
        1174                 :          0 :             return 1;
        1175                 :            :         }
        1176         [ #  # ]:          0 :         for (i = 0; i < len; i++) {
        1177         [ #  # ]:          0 :             if (p[i] == '{')
        1178                 :          0 :                 check = 0;
        1179         [ #  # ]:          0 :             else if (p[i] == '}')
        1180                 :          0 :                 check = 1;
        1181   [ #  #  #  #  :          0 :             else if (check && PATHCHAR(p[i]))
              #  #  #  #  #
                    #  #  # ]
        1182                 :          0 :                 return 1;
        1183                 :            :         }
        1184                 :          0 :         return 0;
        1185                 :            :     }
        1186                 :            :
        1187                 :          0 :     return 1; /* unknown type; might be path expression */
        1188                 :            : }
        1189                 :            :
        1190                 :            : /*[clinic input]
        1191                 :            : _elementtree.Element.extend
        1192                 :            :
        1193                 :            :     cls: defining_class
        1194                 :            :     elements: object
        1195                 :            :     /
        1196                 :            :
        1197                 :            : [clinic start generated code]*/
        1198                 :            :
        1199                 :            : static PyObject *
        1200                 :          0 : _elementtree_Element_extend_impl(ElementObject *self, PyTypeObject *cls,
        1201                 :            :                                  PyObject *elements)
        1202                 :            : /*[clinic end generated code: output=3e86d37fac542216 input=6479b1b5379d09ae]*/
        1203                 :            : {
        1204                 :            :     PyObject* seq;
        1205                 :            :     Py_ssize_t i;
        1206                 :            :
        1207                 :          0 :     seq = PySequence_Fast(elements, "");
        1208         [ #  # ]:          0 :     if (!seq) {
        1209                 :          0 :         PyErr_Format(
        1210                 :            :             PyExc_TypeError,
        1211                 :          0 :             "expected sequence, not \"%.200s\"", Py_TYPE(elements)->tp_name
        1212                 :            :             );
        1213                 :          0 :         return NULL;
        1214                 :            :     }
        1215                 :            :
        1216                 :          0 :     elementtreestate *st = get_elementtree_state_by_cls(cls);
        1217   [ #  #  #  # ]:          0 :     for (i = 0; i < PySequence_Fast_GET_SIZE(seq); i++) {
        1218         [ #  # ]:          0 :         PyObject* element = Py_NewRef(PySequence_Fast_GET_ITEM(seq, i));
        1219         [ #  # ]:          0 :         if (element_add_subelement(st, self, element) < 0) {
        1220                 :          0 :             Py_DECREF(seq);
        1221                 :          0 :             Py_DECREF(element);
        1222                 :          0 :             return NULL;
        1223                 :            :         }
        1224                 :          0 :         Py_DECREF(element);
        1225                 :            :     }
        1226                 :            :
        1227                 :          0 :     Py_DECREF(seq);
        1228                 :            :
        1229                 :          0 :     Py_RETURN_NONE;
        1230                 :            : }
        1231                 :            :
        1232                 :            : /*[clinic input]
        1233                 :            : _elementtree.Element.find
        1234                 :            :
        1235                 :            :     cls: defining_class
        1236                 :            :     /
        1237                 :            :     path: object
        1238                 :            :     namespaces: object = None
        1239                 :            :
        1240                 :            : [clinic start generated code]*/
        1241                 :            :
        1242                 :            : static PyObject *
        1243                 :          0 : _elementtree_Element_find_impl(ElementObject *self, PyTypeObject *cls,
        1244                 :            :                                PyObject *path, PyObject *namespaces)
        1245                 :            : /*[clinic end generated code: output=18f77d393c9fef1b input=94df8a83f956acc6]*/
        1246                 :            : {
        1247                 :            :     Py_ssize_t i;
        1248                 :          0 :     elementtreestate *st = get_elementtree_state_by_cls(cls);
        1249                 :            :
        1250   [ #  #  #  # ]:          0 :     if (checkpath(path) || namespaces != Py_None) {
        1251                 :          0 :         return PyObject_CallMethodObjArgs(
        1252                 :            :             st->elementpath_obj, st->str_find, self, path, namespaces, NULL
        1253                 :            :             );
        1254                 :            :     }
        1255                 :            :
        1256         [ #  # ]:          0 :     if (!self->extra)
        1257                 :          0 :         Py_RETURN_NONE;
        1258                 :            :
        1259         [ #  # ]:          0 :     for (i = 0; i < self->extra->length; i++) {
        1260                 :          0 :         PyObject* item = self->extra->children[i];
        1261                 :            :         int rc;
        1262                 :            :         assert(Element_Check(st, item));
        1263                 :          0 :         Py_INCREF(item);
        1264                 :          0 :         rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
        1265         [ #  # ]:          0 :         if (rc > 0)
        1266                 :          0 :             return item;
        1267                 :          0 :         Py_DECREF(item);
        1268         [ #  # ]:          0 :         if (rc < 0)
        1269                 :          0 :             return NULL;
        1270                 :            :     }
        1271                 :            :
        1272                 :          0 :     Py_RETURN_NONE;
        1273                 :            : }
        1274                 :            :
        1275                 :            : /*[clinic input]
        1276                 :            : _elementtree.Element.findtext
        1277                 :            :
        1278                 :            :     cls: defining_class
        1279                 :            :     /
        1280                 :            :     path: object
        1281                 :            :     default: object = None
        1282                 :            :     namespaces: object = None
        1283                 :            :
        1284                 :            : [clinic start generated code]*/
        1285                 :            :
        1286                 :            : static PyObject *
        1287                 :          0 : _elementtree_Element_findtext_impl(ElementObject *self, PyTypeObject *cls,
        1288                 :            :                                    PyObject *path, PyObject *default_value,
        1289                 :            :                                    PyObject *namespaces)
        1290                 :            : /*[clinic end generated code: output=6af7a2d96aac32cb input=32f252099f62a3d2]*/
        1291                 :            : {
        1292                 :            :     Py_ssize_t i;
        1293                 :          0 :     elementtreestate *st = get_elementtree_state_by_cls(cls);
        1294                 :            :
        1295   [ #  #  #  # ]:          0 :     if (checkpath(path) || namespaces != Py_None)
        1296                 :          0 :         return PyObject_CallMethodObjArgs(
        1297                 :            :             st->elementpath_obj, st->str_findtext,
        1298                 :            :             self, path, default_value, namespaces, NULL
        1299                 :            :             );
        1300                 :            :
        1301         [ #  # ]:          0 :     if (!self->extra) {
        1302                 :          0 :         return Py_NewRef(default_value);
        1303                 :            :     }
        1304                 :            :
        1305         [ #  # ]:          0 :     for (i = 0; i < self->extra->length; i++) {
        1306                 :          0 :         PyObject *item = self->extra->children[i];
        1307                 :            :         int rc;
        1308                 :            :         assert(Element_Check(st, item));
        1309                 :          0 :         Py_INCREF(item);
        1310                 :          0 :         rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
        1311         [ #  # ]:          0 :         if (rc > 0) {
        1312                 :          0 :             PyObject* text = element_get_text((ElementObject*)item);
        1313         [ #  # ]:          0 :             if (text == Py_None) {
        1314                 :          0 :                 Py_DECREF(item);
        1315                 :          0 :                 return PyUnicode_New(0, 0);
        1316                 :            :             }
        1317                 :          0 :             Py_XINCREF(text);
        1318                 :          0 :             Py_DECREF(item);
        1319                 :          0 :             return text;
        1320                 :            :         }
        1321                 :          0 :         Py_DECREF(item);
        1322         [ #  # ]:          0 :         if (rc < 0)
        1323                 :          0 :             return NULL;
        1324                 :            :     }
        1325                 :            :
        1326                 :          0 :     return Py_NewRef(default_value);
        1327                 :            : }
        1328                 :            :
        1329                 :            : /*[clinic input]
        1330                 :            : _elementtree.Element.findall
        1331                 :            :
        1332                 :            :     cls: defining_class
        1333                 :            :     /
        1334                 :            :     path: object
        1335                 :            :     namespaces: object = None
        1336                 :            :
        1337                 :            : [clinic start generated code]*/
        1338                 :            :
        1339                 :            : static PyObject *
        1340                 :          0 : _elementtree_Element_findall_impl(ElementObject *self, PyTypeObject *cls,
        1341                 :            :                                   PyObject *path, PyObject *namespaces)
        1342                 :            : /*[clinic end generated code: output=65e39a1208f3b59e input=7aa0db45673fc9a5]*/
        1343                 :            : {
        1344                 :            :     Py_ssize_t i;
        1345                 :            :     PyObject* out;
        1346                 :          0 :     elementtreestate *st = get_elementtree_state_by_cls(cls);
        1347                 :            :
        1348   [ #  #  #  # ]:          0 :     if (checkpath(path) || namespaces != Py_None) {
        1349                 :          0 :         return PyObject_CallMethodObjArgs(
        1350                 :            :             st->elementpath_obj, st->str_findall, self, path, namespaces, NULL
        1351                 :            :             );
        1352                 :            :     }
        1353                 :            :
        1354                 :          0 :     out = PyList_New(0);
        1355         [ #  # ]:          0 :     if (!out)
        1356                 :          0 :         return NULL;
        1357                 :            :
        1358         [ #  # ]:          0 :     if (!self->extra)
        1359                 :          0 :         return out;
        1360                 :            :
        1361         [ #  # ]:          0 :     for (i = 0; i < self->extra->length; i++) {
        1362                 :          0 :         PyObject* item = self->extra->children[i];
        1363                 :            :         int rc;
        1364                 :            :         assert(Element_Check(st, item));
        1365                 :          0 :         Py_INCREF(item);
        1366                 :          0 :         rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
        1367   [ #  #  #  #  :          0 :         if (rc != 0 && (rc < 0 || PyList_Append(out, item) < 0)) {
                       #  # ]
        1368                 :          0 :             Py_DECREF(item);
        1369                 :          0 :             Py_DECREF(out);
        1370                 :          0 :             return NULL;
        1371                 :            :         }
        1372                 :          0 :         Py_DECREF(item);
        1373                 :            :     }
        1374                 :            :
        1375                 :          0 :     return out;
        1376                 :            : }
        1377                 :            :
        1378                 :            : /*[clinic input]
        1379                 :            : _elementtree.Element.iterfind
        1380                 :            :
        1381                 :            :     cls: defining_class
        1382                 :            :     /
        1383                 :            :     path: object
        1384                 :            :     namespaces: object = None
        1385                 :            :
        1386                 :            : [clinic start generated code]*/
        1387                 :            :
        1388                 :            : static PyObject *
        1389                 :          0 : _elementtree_Element_iterfind_impl(ElementObject *self, PyTypeObject *cls,
        1390                 :            :                                    PyObject *path, PyObject *namespaces)
        1391                 :            : /*[clinic end generated code: output=be5c3f697a14e676 input=88766875a5c9a88b]*/
        1392                 :            : {
        1393                 :          0 :     PyObject* tag = path;
        1394                 :          0 :     elementtreestate *st = get_elementtree_state_by_cls(cls);
        1395                 :            :
        1396                 :          0 :     return PyObject_CallMethodObjArgs(
        1397                 :            :         st->elementpath_obj, st->str_iterfind, self, tag, namespaces, NULL);
        1398                 :            : }
        1399                 :            :
        1400                 :            : /*[clinic input]
        1401                 :            : _elementtree.Element.get
        1402                 :            :
        1403                 :            :     key: object
        1404                 :            :     default: object = None
        1405                 :            :
        1406                 :            : [clinic start generated code]*/
        1407                 :            :
        1408                 :            : static PyObject *
        1409                 :          0 : _elementtree_Element_get_impl(ElementObject *self, PyObject *key,
        1410                 :            :                               PyObject *default_value)
        1411                 :            : /*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/
        1412                 :            : {
        1413   [ #  #  #  # ]:          0 :     if (self->extra && self->extra->attrib) {
        1414                 :          0 :         PyObject *attrib = Py_NewRef(self->extra->attrib);
        1415                 :          0 :         PyObject *value = Py_XNewRef(PyDict_GetItemWithError(attrib, key));
        1416                 :          0 :         Py_DECREF(attrib);
        1417   [ #  #  #  # ]:          0 :         if (value != NULL || PyErr_Occurred()) {
        1418                 :          0 :             return value;
        1419                 :            :         }
        1420                 :            :     }
        1421                 :            :
        1422                 :          0 :     return Py_NewRef(default_value);
        1423                 :            : }
        1424                 :            :
        1425                 :            : static PyObject *
        1426                 :            : create_elementiter(elementtreestate *st, ElementObject *self, PyObject *tag,
        1427                 :            :                    int gettext);
        1428                 :            :
        1429                 :            :
        1430                 :            : /*[clinic input]
        1431                 :            : _elementtree.Element.iter
        1432                 :            :
        1433                 :            :     cls: defining_class
        1434                 :            :     /
        1435                 :            :     tag: object = None
        1436                 :            :
        1437                 :            : [clinic start generated code]*/
        1438                 :            :
        1439                 :            : static PyObject *
        1440                 :          0 : _elementtree_Element_iter_impl(ElementObject *self, PyTypeObject *cls,
        1441                 :            :                                PyObject *tag)
        1442                 :            : /*[clinic end generated code: output=bff29dc5d4566c68 input=f6944c48d3f84c58]*/
        1443                 :            : {
        1444         [ #  # ]:          0 :     if (PyUnicode_Check(tag)) {
        1445         [ #  # ]:          0 :         if (PyUnicode_READY(tag) < 0)
        1446                 :          0 :             return NULL;
        1447   [ #  #  #  # ]:          0 :         if (PyUnicode_GET_LENGTH(tag) == 1 && PyUnicode_READ_CHAR(tag, 0) == '*')
        1448                 :          0 :             tag = Py_None;
        1449                 :            :     }
        1450         [ #  # ]:          0 :     else if (PyBytes_Check(tag)) {
        1451   [ #  #  #  # ]:          0 :         if (PyBytes_GET_SIZE(tag) == 1 && *PyBytes_AS_STRING(tag) == '*')
        1452                 :          0 :             tag = Py_None;
        1453                 :            :     }
        1454                 :            :
        1455                 :          0 :     elementtreestate *st = get_elementtree_state_by_cls(cls);
        1456                 :          0 :     return create_elementiter(st, self, tag, 0);
        1457                 :            : }
        1458                 :            :
        1459                 :            :
        1460                 :            : /*[clinic input]
        1461                 :            : _elementtree.Element.itertext
        1462                 :            :
        1463                 :            :     cls: defining_class
        1464                 :            :     /
        1465                 :            :
        1466                 :            : [clinic start generated code]*/
        1467                 :            :
        1468                 :            : static PyObject *
        1469                 :          0 : _elementtree_Element_itertext_impl(ElementObject *self, PyTypeObject *cls)
        1470                 :            : /*[clinic end generated code: output=fdeb2a3bca0ae063 input=a1ef1f0fc872a586]*/
        1471                 :            : {
        1472                 :          0 :     elementtreestate *st = get_elementtree_state_by_cls(cls);
        1473                 :          0 :     return create_elementiter(st, self, Py_None, 1);
        1474                 :            : }
        1475                 :            :
        1476                 :            :
        1477                 :            : static PyObject*
        1478                 :          0 : element_getitem(PyObject* self_, Py_ssize_t index)
        1479                 :            : {
        1480                 :          0 :     ElementObject* self = (ElementObject*) self_;
        1481                 :            :
        1482   [ #  #  #  #  :          0 :     if (!self->extra || index < 0 || index >= self->extra->length) {
                       #  # ]
        1483                 :          0 :         PyErr_SetString(
        1484                 :            :             PyExc_IndexError,
        1485                 :            :             "child index out of range"
        1486                 :            :             );
        1487                 :          0 :         return NULL;
        1488                 :            :     }
        1489                 :            :
        1490                 :          0 :     return Py_NewRef(self->extra->children[index]);
        1491                 :            : }
        1492                 :            :
        1493                 :            : static int
        1494                 :          0 : element_bool(PyObject* self_)
        1495                 :            : {
        1496                 :          0 :     ElementObject* self = (ElementObject*) self_;
        1497         [ #  # ]:          0 :     if (PyErr_WarnEx(PyExc_DeprecationWarning,
        1498                 :            :                      "Testing an element's truth value will raise an exception "
        1499                 :            :                      "in future versions.  Use specific 'len(elem)' or "
        1500                 :            :                      "'elem is not None' test instead.",
        1501                 :            :                      1) < 0) {
        1502                 :          0 :         return -1;
        1503                 :            :     };
        1504   [ #  #  #  # ]:          0 :     if (self->extra ? self->extra->length : 0) {
        1505                 :          0 :         return 1;
        1506                 :            :     }
        1507                 :          0 :     return 0;
        1508                 :            : }
        1509                 :            :
        1510                 :            : /*[clinic input]
        1511                 :            : _elementtree.Element.insert
        1512                 :            :
        1513                 :            :     index: Py_ssize_t
        1514                 :            :     subelement: object(subclass_of='clinic_state()->Element_Type')
        1515                 :            :     /
        1516                 :            :
        1517                 :            : [clinic start generated code]*/
        1518                 :            :
        1519                 :            : static PyObject *
        1520                 :          0 : _elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index,
        1521                 :            :                                  PyObject *subelement)
        1522                 :            : /*[clinic end generated code: output=990adfef4d424c0b input=9530f4905aa401ca]*/
        1523                 :            : {
        1524                 :            :     Py_ssize_t i;
        1525                 :            :
        1526         [ #  # ]:          0 :     if (!self->extra) {
        1527         [ #  # ]:          0 :         if (create_extra(self, NULL) < 0)
        1528                 :          0 :             return NULL;
        1529                 :            :     }
        1530                 :            :
        1531         [ #  # ]:          0 :     if (index < 0) {
        1532                 :          0 :         index += self->extra->length;
        1533         [ #  # ]:          0 :         if (index < 0)
        1534                 :          0 :             index = 0;
        1535                 :            :     }
        1536         [ #  # ]:          0 :     if (index > self->extra->length)
        1537                 :          0 :         index = self->extra->length;
        1538                 :            :
        1539         [ #  # ]:          0 :     if (element_resize(self, 1) < 0)
        1540                 :          0 :         return NULL;
        1541                 :            :
        1542         [ #  # ]:          0 :     for (i = self->extra->length; i > index; i--)
        1543                 :          0 :         self->extra->children[i] = self->extra->children[i-1];
        1544                 :            :
        1545                 :          0 :     self->extra->children[index] = Py_NewRef(subelement);
        1546                 :            :
        1547                 :          0 :     self->extra->length++;
        1548                 :            :
        1549                 :          0 :     Py_RETURN_NONE;
        1550                 :            : }
        1551                 :            :
        1552                 :            : /*[clinic input]
        1553                 :            : _elementtree.Element.items
        1554                 :            :
        1555                 :            : [clinic start generated code]*/
        1556                 :            :
        1557                 :            : static PyObject *
        1558                 :          0 : _elementtree_Element_items_impl(ElementObject *self)
        1559                 :            : /*[clinic end generated code: output=6db2c778ce3f5a4d input=adbe09aaea474447]*/
        1560                 :            : {
        1561   [ #  #  #  # ]:          0 :     if (!self->extra || !self->extra->attrib)
        1562                 :          0 :         return PyList_New(0);
        1563                 :            :
        1564                 :          0 :     return PyDict_Items(self->extra->attrib);
        1565                 :            : }
        1566                 :            :
        1567                 :            : /*[clinic input]
        1568                 :            : _elementtree.Element.keys
        1569                 :            :
        1570                 :            : [clinic start generated code]*/
        1571                 :            :
        1572                 :            : static PyObject *
        1573                 :          0 : _elementtree_Element_keys_impl(ElementObject *self)
        1574                 :            : /*[clinic end generated code: output=bc5bfabbf20eeb3c input=f02caf5b496b5b0b]*/
        1575                 :            : {
        1576   [ #  #  #  # ]:          0 :     if (!self->extra || !self->extra->attrib)
        1577                 :          0 :         return PyList_New(0);
        1578                 :            :
        1579                 :          0 :     return PyDict_Keys(self->extra->attrib);
        1580                 :            : }
        1581                 :            :
        1582                 :            : static Py_ssize_t
        1583                 :          0 : element_length(ElementObject* self)
        1584                 :            : {
        1585         [ #  # ]:          0 :     if (!self->extra)
        1586                 :          0 :         return 0;
        1587                 :            :
        1588                 :          0 :     return self->extra->length;
        1589                 :            : }
        1590                 :            :
        1591                 :            : /*[clinic input]
        1592                 :            : _elementtree.Element.makeelement
        1593                 :            :
        1594                 :            :     cls: defining_class
        1595                 :            :     tag: object
        1596                 :            :     attrib: object(subclass_of='&PyDict_Type')
        1597                 :            :     /
        1598                 :            :
        1599                 :            : [clinic start generated code]*/
        1600                 :            :
        1601                 :            : static PyObject *
        1602                 :          0 : _elementtree_Element_makeelement_impl(ElementObject *self, PyTypeObject *cls,
        1603                 :            :                                       PyObject *tag, PyObject *attrib)
        1604                 :            : /*[clinic end generated code: output=d50bb17a47077d47 input=589829dab92f26e8]*/
        1605                 :            : {
        1606                 :            :     PyObject* elem;
        1607                 :            :
        1608                 :          0 :     attrib = PyDict_Copy(attrib);
        1609         [ #  # ]:          0 :     if (!attrib)
        1610                 :          0 :         return NULL;
        1611                 :            :
        1612                 :          0 :     elementtreestate *st = get_elementtree_state_by_cls(cls);
        1613                 :          0 :     elem = create_new_element(st, tag, attrib);
        1614                 :            :
        1615                 :          0 :     Py_DECREF(attrib);
        1616                 :            :
        1617                 :          0 :     return elem;
        1618                 :            : }
        1619                 :            :
        1620                 :            : /*[clinic input]
        1621                 :            : _elementtree.Element.remove
        1622                 :            :
        1623                 :            :     subelement: object(subclass_of='clinic_state()->Element_Type')
        1624                 :            :     /
        1625                 :            :
        1626                 :            : [clinic start generated code]*/
        1627                 :            :
        1628                 :            : static PyObject *
        1629                 :          0 : _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement)
        1630                 :            : /*[clinic end generated code: output=38fe6c07d6d87d1f input=6133e1d05597d5ee]*/
        1631                 :            : {
        1632                 :            :     Py_ssize_t i;
        1633                 :            :     int rc;
        1634                 :            :     PyObject *found;
        1635                 :            :
        1636         [ #  # ]:          0 :     if (!self->extra) {
        1637                 :            :         /* element has no children, so raise exception */
        1638                 :          0 :         PyErr_SetString(
        1639                 :            :             PyExc_ValueError,
        1640                 :            :             "list.remove(x): x not in list"
        1641                 :            :             );
        1642                 :          0 :         return NULL;
        1643                 :            :     }
        1644                 :            :
        1645         [ #  # ]:          0 :     for (i = 0; i < self->extra->length; i++) {
        1646         [ #  # ]:          0 :         if (self->extra->children[i] == subelement)
        1647                 :          0 :             break;
        1648                 :          0 :         rc = PyObject_RichCompareBool(self->extra->children[i], subelement, Py_EQ);
        1649         [ #  # ]:          0 :         if (rc > 0)
        1650                 :          0 :             break;
        1651         [ #  # ]:          0 :         if (rc < 0)
        1652                 :          0 :             return NULL;
        1653                 :            :     }
        1654                 :            :
        1655         [ #  # ]:          0 :     if (i >= self->extra->length) {
        1656                 :            :         /* subelement is not in children, so raise exception */
        1657                 :          0 :         PyErr_SetString(
        1658                 :            :             PyExc_ValueError,
        1659                 :            :             "list.remove(x): x not in list"
        1660                 :            :             );
        1661                 :          0 :         return NULL;
        1662                 :            :     }
        1663                 :            :
        1664                 :          0 :     found = self->extra->children[i];
        1665                 :            :
        1666                 :          0 :     self->extra->length--;
        1667         [ #  # ]:          0 :     for (; i < self->extra->length; i++)
        1668                 :          0 :         self->extra->children[i] = self->extra->children[i+1];
        1669                 :            :
        1670                 :          0 :     Py_DECREF(found);
        1671                 :          0 :     Py_RETURN_NONE;
        1672                 :            : }
        1673                 :            :
        1674                 :            : static PyObject*
        1675                 :          0 : element_repr(ElementObject* self)
        1676                 :            : {
        1677                 :            :     int status;
        1678                 :            :
        1679         [ #  # ]:          0 :     if (self->tag == NULL)
        1680                 :          0 :         return PyUnicode_FromFormat("<Element at %p>", self);
        1681                 :            :
        1682                 :          0 :     status = Py_ReprEnter((PyObject *)self);
        1683         [ #  # ]:          0 :     if (status == 0) {
        1684                 :            :         PyObject *res;
        1685                 :          0 :         res = PyUnicode_FromFormat("<Element %R at %p>", self->tag, self);
        1686                 :          0 :         Py_ReprLeave((PyObject *)self);
        1687                 :          0 :         return res;
        1688                 :            :     }
        1689         [ #  # ]:          0 :     if (status > 0)
        1690                 :          0 :         PyErr_Format(PyExc_RuntimeError,
        1691                 :            :                      "reentrant call inside %s.__repr__",
        1692                 :          0 :                      Py_TYPE(self)->tp_name);
        1693                 :          0 :     return NULL;
        1694                 :            : }
        1695                 :            :
        1696                 :            : /*[clinic input]
        1697                 :            : _elementtree.Element.set
        1698                 :            :
        1699                 :            :     key: object
        1700                 :            :     value: object
        1701                 :            :     /
        1702                 :            :
        1703                 :            : [clinic start generated code]*/
        1704                 :            :
        1705                 :            : static PyObject *
        1706                 :          0 : _elementtree_Element_set_impl(ElementObject *self, PyObject *key,
        1707                 :            :                               PyObject *value)
        1708                 :            : /*[clinic end generated code: output=fb938806be3c5656 input=1efe90f7d82b3fe9]*/
        1709                 :            : {
        1710                 :            :     PyObject* attrib;
        1711                 :            :
        1712         [ #  # ]:          0 :     if (!self->extra) {
        1713         [ #  # ]:          0 :         if (create_extra(self, NULL) < 0)
        1714                 :          0 :             return NULL;
        1715                 :            :     }
        1716                 :            :
        1717                 :          0 :     attrib = element_get_attrib(self);
        1718         [ #  # ]:          0 :     if (!attrib)
        1719                 :          0 :         return NULL;
        1720                 :            :
        1721         [ #  # ]:          0 :     if (PyDict_SetItem(attrib, key, value) < 0)
        1722                 :          0 :         return NULL;
        1723                 :            :
        1724                 :          0 :     Py_RETURN_NONE;
        1725                 :            : }
        1726                 :            :
        1727                 :            : static int
        1728                 :          0 : element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
        1729                 :            : {
        1730                 :          0 :     ElementObject* self = (ElementObject*) self_;
        1731                 :            :     Py_ssize_t i;
        1732                 :            :     PyObject* old;
        1733                 :            :
        1734   [ #  #  #  #  :          0 :     if (!self->extra || index < 0 || index >= self->extra->length) {
                       #  # ]
        1735                 :          0 :         PyErr_SetString(
        1736                 :            :             PyExc_IndexError,
        1737                 :            :             "child assignment index out of range");
        1738                 :          0 :         return -1;
        1739                 :            :     }
        1740                 :            :
        1741                 :          0 :     old = self->extra->children[index];
        1742                 :            :
        1743         [ #  # ]:          0 :     if (item) {
        1744                 :          0 :         PyTypeObject *tp = Py_TYPE(self);
        1745                 :          0 :         elementtreestate *st = get_elementtree_state_by_type(tp);
        1746         [ #  # ]:          0 :         if (!Element_Check(st, item)) {
        1747                 :          0 :             raise_type_error(item);
        1748                 :          0 :             return -1;
        1749                 :            :         }
        1750                 :          0 :         self->extra->children[index] = Py_NewRef(item);
        1751                 :            :     } else {
        1752                 :          0 :         self->extra->length--;
        1753         [ #  # ]:          0 :         for (i = index; i < self->extra->length; i++)
        1754                 :          0 :             self->extra->children[i] = self->extra->children[i+1];
        1755                 :            :     }
        1756                 :            :
        1757                 :          0 :     Py_DECREF(old);
        1758                 :            :
        1759                 :          0 :     return 0;
        1760                 :            : }
        1761                 :            :
        1762                 :            : static PyObject*
        1763                 :          0 : element_subscr(PyObject* self_, PyObject* item)
        1764                 :            : {
        1765                 :          0 :     ElementObject* self = (ElementObject*) self_;
        1766                 :            :
        1767         [ #  # ]:          0 :     if (PyIndex_Check(item)) {
        1768                 :          0 :         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
        1769                 :            :
        1770   [ #  #  #  # ]:          0 :         if (i == -1 && PyErr_Occurred()) {
        1771                 :          0 :             return NULL;
        1772                 :            :         }
        1773   [ #  #  #  # ]:          0 :         if (i < 0 && self->extra)
        1774                 :          0 :             i += self->extra->length;
        1775                 :          0 :         return element_getitem(self_, i);
        1776                 :            :     }
        1777         [ #  # ]:          0 :     else if (PySlice_Check(item)) {
        1778                 :            :         Py_ssize_t start, stop, step, slicelen, i;
        1779                 :            :         size_t cur;
        1780                 :            :         PyObject* list;
        1781                 :            :
        1782         [ #  # ]:          0 :         if (!self->extra)
        1783                 :          0 :             return PyList_New(0);
        1784                 :            :
        1785         [ #  # ]:          0 :         if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
        1786                 :          0 :             return NULL;
        1787                 :            :         }
        1788                 :          0 :         slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop,
        1789                 :            :                                          step);
        1790                 :            :
        1791         [ #  # ]:          0 :         if (slicelen <= 0)
        1792                 :          0 :             return PyList_New(0);
        1793                 :            :         else {
        1794                 :          0 :             list = PyList_New(slicelen);
        1795         [ #  # ]:          0 :             if (!list)
        1796                 :          0 :                 return NULL;
        1797                 :            :
        1798         [ #  # ]:          0 :             for (cur = start, i = 0; i < slicelen;
        1799                 :          0 :                  cur += step, i++) {
        1800                 :          0 :                 PyObject* item = Py_NewRef(self->extra->children[cur]);
        1801                 :          0 :                 PyList_SET_ITEM(list, i, item);
        1802                 :            :             }
        1803                 :            :
        1804                 :          0 :             return list;
        1805                 :            :         }
        1806                 :            :     }
        1807                 :            :     else {
        1808                 :          0 :         PyErr_SetString(PyExc_TypeError,
        1809                 :            :                 "element indices must be integers");
        1810                 :          0 :         return NULL;
        1811                 :            :     }
        1812                 :            : }
        1813                 :            :
        1814                 :            : static int
        1815                 :          0 : element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
        1816                 :            : {
        1817                 :          0 :     ElementObject* self = (ElementObject*) self_;
        1818                 :            :
        1819         [ #  # ]:          0 :     if (PyIndex_Check(item)) {
        1820                 :          0 :         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
        1821                 :            :
        1822   [ #  #  #  # ]:          0 :         if (i == -1 && PyErr_Occurred()) {
        1823                 :          0 :             return -1;
        1824                 :            :         }
        1825   [ #  #  #  # ]:          0 :         if (i < 0 && self->extra)
        1826                 :          0 :             i += self->extra->length;
        1827                 :          0 :         return element_setitem(self_, i, value);
        1828                 :            :     }
        1829         [ #  # ]:          0 :     else if (PySlice_Check(item)) {
        1830                 :            :         Py_ssize_t start, stop, step, slicelen, newlen, i;
        1831                 :            :         size_t cur;
        1832                 :            :
        1833                 :          0 :         PyObject* recycle = NULL;
        1834                 :            :         PyObject* seq;
        1835                 :            :
        1836         [ #  # ]:          0 :         if (!self->extra) {
        1837         [ #  # ]:          0 :             if (create_extra(self, NULL) < 0)
        1838                 :          0 :                 return -1;
        1839                 :            :         }
        1840                 :            :
        1841         [ #  # ]:          0 :         if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
        1842                 :          0 :             return -1;
        1843                 :            :         }
        1844                 :          0 :         slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop,
        1845                 :            :                                          step);
        1846                 :            :
        1847         [ #  # ]:          0 :         if (value == NULL) {
        1848                 :            :             /* Delete slice */
        1849                 :            :             size_t cur;
        1850                 :            :             Py_ssize_t i;
        1851                 :            :
        1852         [ #  # ]:          0 :             if (slicelen <= 0)
        1853                 :          0 :                 return 0;
        1854                 :            :
        1855                 :            :             /* Since we're deleting, the direction of the range doesn't matter,
        1856                 :            :              * so for simplicity make it always ascending.
        1857                 :            :             */
        1858         [ #  # ]:          0 :             if (step < 0) {
        1859                 :          0 :                 stop = start + 1;
        1860                 :          0 :                 start = stop + step * (slicelen - 1) - 1;
        1861                 :          0 :                 step = -step;
        1862                 :            :             }
        1863                 :            :
        1864                 :            :             assert((size_t)slicelen <= SIZE_MAX / sizeof(PyObject *));
        1865                 :            :
        1866                 :            :             /* recycle is a list that will contain all the children
        1867                 :            :              * scheduled for removal.
        1868                 :            :             */
        1869         [ #  # ]:          0 :             if (!(recycle = PyList_New(slicelen))) {
        1870                 :          0 :                 return -1;
        1871                 :            :             }
        1872                 :            :
        1873                 :            :             /* This loop walks over all the children that have to be deleted,
        1874                 :            :              * with cur pointing at them. num_moved is the amount of children
        1875                 :            :              * until the next deleted child that have to be "shifted down" to
        1876                 :            :              * occupy the deleted's places.
        1877                 :            :              * Note that in the ith iteration, shifting is done i+i places down
        1878                 :            :              * because i children were already removed.
        1879                 :            :             */
        1880         [ #  # ]:          0 :             for (cur = start, i = 0; cur < (size_t)stop; cur += step, ++i) {
        1881                 :            :                 /* Compute how many children have to be moved, clipping at the
        1882                 :            :                  * list end.
        1883                 :            :                 */
        1884                 :          0 :                 Py_ssize_t num_moved = step - 1;
        1885         [ #  # ]:          0 :                 if (cur + step >= (size_t)self->extra->length) {
        1886                 :          0 :                     num_moved = self->extra->length - cur - 1;
        1887                 :            :                 }
        1888                 :            :
        1889                 :          0 :                 PyList_SET_ITEM(recycle, i, self->extra->children[cur]);
        1890                 :            :
        1891                 :          0 :                 memmove(
        1892                 :          0 :                     self->extra->children + cur - i,
        1893                 :          0 :                     self->extra->children + cur + 1,
        1894                 :            :                     num_moved * sizeof(PyObject *));
        1895                 :            :             }
        1896                 :            :
        1897                 :            :             /* Leftover "tail" after the last removed child */
        1898                 :          0 :             cur = start + (size_t)slicelen * step;
        1899         [ #  # ]:          0 :             if (cur < (size_t)self->extra->length) {
        1900                 :          0 :                 memmove(
        1901                 :          0 :                     self->extra->children + cur - slicelen,
        1902                 :          0 :                     self->extra->children + cur,
        1903                 :          0 :                     (self->extra->length - cur) * sizeof(PyObject *));
        1904                 :            :             }
        1905                 :            :
        1906                 :          0 :             self->extra->length -= slicelen;
        1907                 :            :
        1908                 :            :             /* Discard the recycle list with all the deleted sub-elements */
        1909                 :          0 :             Py_DECREF(recycle);
        1910                 :          0 :             return 0;
        1911                 :            :         }
        1912                 :            :
        1913                 :            :         /* A new slice is actually being assigned */
        1914                 :          0 :         seq = PySequence_Fast(value, "");
        1915         [ #  # ]:          0 :         if (!seq) {
        1916                 :          0 :             PyErr_Format(
        1917                 :            :                 PyExc_TypeError,
        1918                 :          0 :                 "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name
        1919                 :            :                 );
        1920                 :          0 :             return -1;
        1921                 :            :         }
        1922         [ #  # ]:          0 :         newlen = PySequence_Fast_GET_SIZE(seq);
        1923                 :            :
        1924   [ #  #  #  # ]:          0 :         if (step !=  1 && newlen != slicelen)
        1925                 :            :         {
        1926                 :          0 :             Py_DECREF(seq);
        1927                 :          0 :             PyErr_Format(PyExc_ValueError,
        1928                 :            :                 "attempt to assign sequence of size %zd "
        1929                 :            :                 "to extended slice of size %zd",
        1930                 :            :                 newlen, slicelen
        1931                 :            :                 );
        1932                 :          0 :             return -1;
        1933                 :            :         }
        1934                 :            :
        1935                 :            :         /* Resize before creating the recycle bin, to prevent refleaks. */
        1936         [ #  # ]:          0 :         if (newlen > slicelen) {
        1937         [ #  # ]:          0 :             if (element_resize(self, newlen - slicelen) < 0) {
        1938                 :          0 :                 Py_DECREF(seq);
        1939                 :          0 :                 return -1;
        1940                 :            :             }
        1941                 :            :         }
        1942                 :            :
        1943                 :          0 :         PyTypeObject *tp = Py_TYPE(self);
        1944                 :          0 :         elementtreestate *st = get_elementtree_state_by_type(tp);
        1945         [ #  # ]:          0 :         for (i = 0; i < newlen; i++) {
        1946         [ #  # ]:          0 :             PyObject *element = PySequence_Fast_GET_ITEM(seq, i);
        1947         [ #  # ]:          0 :             if (!Element_Check(st, element)) {
        1948                 :          0 :                 raise_type_error(element);
        1949                 :          0 :                 Py_DECREF(seq);
        1950                 :          0 :                 return -1;
        1951                 :            :             }
        1952                 :            :         }
        1953                 :            :
        1954         [ #  # ]:          0 :         if (slicelen > 0) {
        1955                 :            :             /* to avoid recursive calls to this method (via decref), move
        1956                 :            :                old items to the recycle bin here, and get rid of them when
        1957                 :            :                we're done modifying the element */
        1958                 :          0 :             recycle = PyList_New(slicelen);
        1959         [ #  # ]:          0 :             if (!recycle) {
        1960                 :          0 :                 Py_DECREF(seq);
        1961                 :          0 :                 return -1;
        1962                 :            :             }
        1963         [ #  # ]:          0 :             for (cur = start, i = 0; i < slicelen;
        1964                 :          0 :                  cur += step, i++)
        1965                 :          0 :                 PyList_SET_ITEM(recycle, i, self->extra->children[cur]);
        1966                 :            :         }
        1967                 :            :
        1968         [ #  # ]:          0 :         if (newlen < slicelen) {
        1969                 :            :             /* delete slice */
        1970         [ #  # ]:          0 :             for (i = stop; i < self->extra->length; i++)
        1971                 :          0 :                 self->extra->children[i + newlen - slicelen] = self->extra->children[i];
        1972         [ #  # ]:          0 :         } else if (newlen > slicelen) {
        1973                 :            :             /* insert slice */
        1974         [ #  # ]:          0 :             for (i = self->extra->length-1; i >= stop; i--)
        1975                 :          0 :                 self->extra->children[i + newlen - slicelen] = self->extra->children[i];
        1976                 :            :         }
        1977                 :            :
        1978                 :            :         /* replace the slice */
        1979         [ #  # ]:          0 :         for (cur = start, i = 0; i < newlen;
        1980                 :          0 :              cur += step, i++) {
        1981         [ #  # ]:          0 :             PyObject* element = PySequence_Fast_GET_ITEM(seq, i);
        1982                 :          0 :             self->extra->children[cur] = Py_NewRef(element);
        1983                 :            :         }
        1984                 :            :
        1985                 :          0 :         self->extra->length += newlen - slicelen;
        1986                 :            :
        1987                 :          0 :         Py_DECREF(seq);
        1988                 :            :
        1989                 :            :         /* discard the recycle bin, and everything in it */
        1990                 :          0 :         Py_XDECREF(recycle);
        1991                 :            :
        1992                 :          0 :         return 0;
        1993                 :            :     }
        1994                 :            :     else {
        1995                 :          0 :         PyErr_SetString(PyExc_TypeError,
        1996                 :            :                 "element indices must be integers");
        1997                 :          0 :         return -1;
        1998                 :            :     }
        1999                 :            : }
        2000                 :            :
        2001                 :            : static PyObject*
        2002                 :          0 : element_tag_getter(ElementObject *self, void *closure)
        2003                 :            : {
        2004                 :          0 :     PyObject *res = self->tag;
        2005                 :          0 :     return Py_NewRef(res);
        2006                 :            : }
        2007                 :            :
        2008                 :            : static PyObject*
        2009                 :          0 : element_text_getter(ElementObject *self, void *closure)
        2010                 :            : {
        2011                 :          0 :     PyObject *res = element_get_text(self);
        2012                 :          0 :     return Py_XNewRef(res);
        2013                 :            : }
        2014                 :            :
        2015                 :            : static PyObject*
        2016                 :          0 : element_tail_getter(ElementObject *self, void *closure)
        2017                 :            : {
        2018                 :          0 :     PyObject *res = element_get_tail(self);
        2019                 :          0 :     return Py_XNewRef(res);
        2020                 :            : }
        2021                 :            :
        2022                 :            : static PyObject*
        2023                 :          0 : element_attrib_getter(ElementObject *self, void *closure)
        2024                 :            : {
        2025                 :            :     PyObject *res;
        2026         [ #  # ]:          0 :     if (!self->extra) {
        2027         [ #  # ]:          0 :         if (create_extra(self, NULL) < 0)
        2028                 :          0 :             return NULL;
        2029                 :            :     }
        2030                 :          0 :     res = element_get_attrib(self);
        2031                 :          0 :     return Py_XNewRef(res);
        2032                 :            : }
        2033                 :            :
        2034                 :            : /* macro for setter validation */
        2035                 :            : #define _VALIDATE_ATTR_VALUE(V)                     \
        2036                 :            :     if ((V) == NULL) {                              \
        2037                 :            :         PyErr_SetString(                            \
        2038                 :            :             PyExc_AttributeError,                   \
        2039                 :            :             "can't delete element attribute");      \
        2040                 :            :         return -1;                                  \
        2041                 :            :     }
        2042                 :            :
        2043                 :            : static int
        2044                 :          0 : element_tag_setter(ElementObject *self, PyObject *value, void *closure)
        2045                 :            : {
        2046         [ #  # ]:          0 :     _VALIDATE_ATTR_VALUE(value);
        2047                 :          0 :     Py_SETREF(self->tag, Py_NewRef(value));
        2048                 :          0 :     return 0;
        2049                 :            : }
        2050                 :            :
        2051                 :            : static int
        2052                 :          0 : element_text_setter(ElementObject *self, PyObject *value, void *closure)
        2053                 :            : {
        2054         [ #  # ]:          0 :     _VALIDATE_ATTR_VALUE(value);
        2055                 :          0 :     _set_joined_ptr(&self->text, Py_NewRef(value));
        2056                 :          0 :     return 0;
        2057                 :            : }
        2058                 :            :
        2059                 :            : static int
        2060                 :          0 : element_tail_setter(ElementObject *self, PyObject *value, void *closure)
        2061                 :            : {
        2062         [ #  # ]:          0 :     _VALIDATE_ATTR_VALUE(value);
        2063                 :          0 :     _set_joined_ptr(&self->tail, Py_NewRef(value));
        2064                 :          0 :     return 0;
        2065                 :            : }
        2066                 :            :
        2067                 :            : static int
        2068                 :          0 : element_attrib_setter(ElementObject *self, PyObject *value, void *closure)
        2069                 :            : {
        2070         [ #  # ]:          0 :     _VALIDATE_ATTR_VALUE(value);
        2071         [ #  # ]:          0 :     if (!PyDict_Check(value)) {
        2072                 :          0 :         PyErr_Format(PyExc_TypeError,
        2073                 :            :                      "attrib must be dict, not %.200s",
        2074                 :          0 :                      Py_TYPE(value)->tp_name);
        2075                 :          0 :         return -1;
        2076                 :            :     }
        2077         [ #  # ]:          0 :     if (!self->extra) {
        2078         [ #  # ]:          0 :         if (create_extra(self, NULL) < 0)
        2079                 :          0 :             return -1;
        2080                 :            :     }
        2081                 :          0 :     Py_XSETREF(self->extra->attrib, Py_NewRef(value));
        2082                 :          0 :     return 0;
        2083                 :            : }
        2084                 :            :
        2085                 :            : /******************************* Element iterator ****************************/
        2086                 :            :
        2087                 :            : /* ElementIterObject represents the iteration state over an XML element in
        2088                 :            :  * pre-order traversal. To keep track of which sub-element should be returned
        2089                 :            :  * next, a stack of parents is maintained. This is a standard stack-based
        2090                 :            :  * iterative pre-order traversal of a tree.
        2091                 :            :  * The stack is managed using a continuous array.
        2092                 :            :  * Each stack item contains the saved parent to which we should return after
        2093                 :            :  * the current one is exhausted, and the next child to examine in that parent.
        2094                 :            :  */
        2095                 :            : typedef struct ParentLocator_t {
        2096                 :            :     ElementObject *parent;
        2097                 :            :     Py_ssize_t child_index;
        2098                 :            : } ParentLocator;
        2099                 :            :
        2100                 :            : typedef struct {
        2101                 :            :     PyObject_HEAD
        2102                 :            :     ParentLocator *parent_stack;
        2103                 :            :     Py_ssize_t parent_stack_used;
        2104                 :            :     Py_ssize_t parent_stack_size;
        2105                 :            :     ElementObject *root_element;
        2106                 :            :     PyObject *sought_tag;
        2107                 :            :     int gettext;
        2108                 :            : } ElementIterObject;
        2109                 :            :
        2110                 :            :
        2111                 :            : static void
        2112                 :          0 : elementiter_dealloc(ElementIterObject *it)
        2113                 :            : {
        2114                 :          0 :     PyTypeObject *tp = Py_TYPE(it);
        2115                 :          0 :     Py_ssize_t i = it->parent_stack_used;
        2116                 :          0 :     it->parent_stack_used = 0;
        2117                 :            :     /* bpo-31095: UnTrack is needed before calling any callbacks */
        2118                 :          0 :     PyObject_GC_UnTrack(it);
        2119         [ #  # ]:          0 :     while (i--)
        2120                 :          0 :         Py_XDECREF(it->parent_stack[i].parent);
        2121                 :          0 :     PyMem_Free(it->parent_stack);
        2122                 :            :
        2123                 :          0 :     Py_XDECREF(it->sought_tag);
        2124                 :          0 :     Py_XDECREF(it->root_element);
        2125                 :            :
        2126                 :          0 :     tp->tp_free(it);
        2127                 :          0 :     Py_DECREF(tp);
        2128                 :          0 : }
        2129                 :            :
        2130                 :            : static int
        2131                 :          0 : elementiter_traverse(ElementIterObject *it, visitproc visit, void *arg)
        2132                 :            : {
        2133                 :          0 :     Py_ssize_t i = it->parent_stack_used;
        2134         [ #  # ]:          0 :     while (i--)
        2135   [ #  #  #  # ]:          0 :         Py_VISIT(it->parent_stack[i].parent);
        2136                 :            :
        2137   [ #  #  #  # ]:          0 :     Py_VISIT(it->root_element);
        2138   [ #  #  #  # ]:          0 :     Py_VISIT(it->sought_tag);
        2139   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(it));
        2140                 :          0 :     return 0;
        2141                 :            : }
        2142                 :            :
        2143                 :            : /* Helper function for elementiter_next. Add a new parent to the parent stack.
        2144                 :            :  */
        2145                 :            : static int
        2146                 :          0 : parent_stack_push_new(ElementIterObject *it, ElementObject *parent)
        2147                 :            : {
        2148                 :            :     ParentLocator *item;
        2149                 :            :
        2150         [ #  # ]:          0 :     if (it->parent_stack_used >= it->parent_stack_size) {
        2151                 :          0 :         Py_ssize_t new_size = it->parent_stack_size * 2;  /* never overflow */
        2152                 :          0 :         ParentLocator *parent_stack = it->parent_stack;
        2153         [ #  # ]:          0 :         PyMem_Resize(parent_stack, ParentLocator, new_size);
        2154         [ #  # ]:          0 :         if (parent_stack == NULL)
        2155                 :          0 :             return -1;
        2156                 :          0 :         it->parent_stack = parent_stack;
        2157                 :          0 :         it->parent_stack_size = new_size;
        2158                 :            :     }
        2159                 :          0 :     item = it->parent_stack + it->parent_stack_used++;
        2160                 :          0 :     item->parent = (ElementObject*)Py_NewRef(parent);
        2161                 :          0 :     item->child_index = 0;
        2162                 :          0 :     return 0;
        2163                 :            : }
        2164                 :            :
        2165                 :            : static PyObject *
        2166                 :          0 : elementiter_next(ElementIterObject *it)
        2167                 :            : {
        2168                 :            :     /* Sub-element iterator.
        2169                 :            :      *
        2170                 :            :      * A short note on gettext: this function serves both the iter() and
        2171                 :            :      * itertext() methods to avoid code duplication. However, there are a few
        2172                 :            :      * small differences in the way these iterations work. Namely:
        2173                 :            :      *   - itertext() only yields text from nodes that have it, and continues
        2174                 :            :      *     iterating when a node doesn't have text (so it doesn't return any
        2175                 :            :      *     node like iter())
        2176                 :            :      *   - itertext() also has to handle tail, after finishing with all the
        2177                 :            :      *     children of a node.
        2178                 :            :      */
        2179                 :            :     int rc;
        2180                 :            :     ElementObject *elem;
        2181                 :            :     PyObject *text;
        2182                 :            :
        2183                 :            :     while (1) {
        2184                 :            :         /* Handle the case reached in the beginning and end of iteration, where
        2185                 :            :          * the parent stack is empty. If root_element is NULL and we're here, the
        2186                 :            :          * iterator is exhausted.
        2187                 :            :          */
        2188         [ #  # ]:          0 :         if (!it->parent_stack_used) {
        2189         [ #  # ]:          0 :             if (!it->root_element) {
        2190                 :          0 :                 PyErr_SetNone(PyExc_StopIteration);
        2191                 :          0 :                 return NULL;
        2192                 :            :             }
        2193                 :            :
        2194                 :          0 :             elem = it->root_element;  /* steals a reference */
        2195                 :          0 :             it->root_element = NULL;
        2196                 :            :         }
        2197                 :            :         else {
        2198                 :            :             /* See if there are children left to traverse in the current parent. If
        2199                 :            :              * yes, visit the next child. If not, pop the stack and try again.
        2200                 :            :              */
        2201                 :          0 :             ParentLocator *item = &it->parent_stack[it->parent_stack_used - 1];
        2202                 :          0 :             Py_ssize_t child_index = item->child_index;
        2203                 :            :             ElementObjectExtra *extra;
        2204                 :          0 :             elem = item->parent;
        2205                 :          0 :             extra = elem->extra;
        2206   [ #  #  #  # ]:          0 :             if (!extra || child_index >= extra->length) {
        2207                 :          0 :                 it->parent_stack_used--;
        2208                 :            :                 /* Note that extra condition on it->parent_stack_used here;
        2209                 :            :                  * this is because itertext() is supposed to only return *inner*
        2210                 :            :                  * text, not text following the element it began iteration with.
        2211                 :            :                  */
        2212   [ #  #  #  # ]:          0 :                 if (it->gettext && it->parent_stack_used) {
        2213                 :          0 :                     text = element_get_tail(elem);
        2214                 :          0 :                     goto gettext;
        2215                 :            :                 }
        2216                 :          0 :                 Py_DECREF(elem);
        2217                 :          0 :                 continue;
        2218                 :            :             }
        2219                 :            :
        2220                 :            : #ifndef NDEBUG
        2221                 :            :             PyTypeObject *tp = Py_TYPE(it);
        2222                 :            :             elementtreestate *st = get_elementtree_state_by_type(tp);
        2223                 :            :             assert(Element_Check(st, extra->children[child_index]));
        2224                 :            : #endif
        2225                 :          0 :             elem = (ElementObject *)Py_NewRef(extra->children[child_index]);
        2226                 :          0 :             item->child_index++;
        2227                 :            :         }
        2228                 :            :
        2229         [ #  # ]:          0 :         if (parent_stack_push_new(it, elem) < 0) {
        2230                 :          0 :             Py_DECREF(elem);
        2231                 :          0 :             PyErr_NoMemory();
        2232                 :          0 :             return NULL;
        2233                 :            :         }
        2234         [ #  # ]:          0 :         if (it->gettext) {
        2235                 :          0 :             text = element_get_text(elem);
        2236                 :          0 :             goto gettext;
        2237                 :            :         }
        2238                 :            :
        2239         [ #  # ]:          0 :         if (it->sought_tag == Py_None)
        2240                 :          0 :             return (PyObject *)elem;
        2241                 :            :
        2242                 :          0 :         rc = PyObject_RichCompareBool(elem->tag, it->sought_tag, Py_EQ);
        2243         [ #  # ]:          0 :         if (rc > 0)
        2244                 :          0 :             return (PyObject *)elem;
        2245                 :            :
        2246                 :          0 :         Py_DECREF(elem);
        2247         [ #  # ]:          0 :         if (rc < 0)
        2248                 :          0 :             return NULL;
        2249                 :          0 :         continue;
        2250                 :            :
        2251                 :          0 : gettext:
        2252         [ #  # ]:          0 :         if (!text) {
        2253                 :          0 :             Py_DECREF(elem);
        2254                 :          0 :             return NULL;
        2255                 :            :         }
        2256         [ #  # ]:          0 :         if (text == Py_None) {
        2257                 :          0 :             Py_DECREF(elem);
        2258                 :            :         }
        2259                 :            :         else {
        2260                 :          0 :             Py_INCREF(text);
        2261                 :          0 :             Py_DECREF(elem);
        2262                 :          0 :             rc = PyObject_IsTrue(text);
        2263         [ #  # ]:          0 :             if (rc > 0)
        2264                 :          0 :                 return text;
        2265                 :          0 :             Py_DECREF(text);
        2266         [ #  # ]:          0 :             if (rc < 0)
        2267                 :          0 :                 return NULL;
        2268                 :            :         }
        2269                 :            :     }
        2270                 :            :
        2271                 :            :     return NULL;
        2272                 :            : }
        2273                 :            :
        2274                 :            : static PyType_Slot elementiter_slots[] = {
        2275                 :            :     {Py_tp_dealloc, elementiter_dealloc},
        2276                 :            :     {Py_tp_traverse, elementiter_traverse},
        2277                 :            :     {Py_tp_iter, PyObject_SelfIter},
        2278                 :            :     {Py_tp_iternext, elementiter_next},
        2279                 :            :     {0, NULL},
        2280                 :            : };
        2281                 :            :
        2282                 :            : static PyType_Spec elementiter_spec = {
        2283                 :            :     /* Using the module's name since the pure-Python implementation does not
        2284                 :            :        have such a type. */
        2285                 :            :     .name = "_elementtree._element_iterator",
        2286                 :            :     .basicsize = sizeof(ElementIterObject),
        2287                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        2288                 :            :               Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
        2289                 :            :     .slots = elementiter_slots,
        2290                 :            : };
        2291                 :            :
        2292                 :            : #define INIT_PARENT_STACK_SIZE 8
        2293                 :            :
        2294                 :            : static PyObject *
        2295                 :          0 : create_elementiter(elementtreestate *st, ElementObject *self, PyObject *tag,
        2296                 :            :                    int gettext)
        2297                 :            : {
        2298                 :            :     ElementIterObject *it;
        2299                 :            :
        2300                 :          0 :     it = PyObject_GC_New(ElementIterObject, st->ElementIter_Type);
        2301         [ #  # ]:          0 :     if (!it)
        2302                 :          0 :         return NULL;
        2303                 :            :
        2304                 :          0 :     it->sought_tag = Py_NewRef(tag);
        2305                 :          0 :     it->gettext = gettext;
        2306                 :          0 :     it->root_element = (ElementObject*)Py_NewRef(self);
        2307                 :            :
        2308                 :          0 :     it->parent_stack = PyMem_New(ParentLocator, INIT_PARENT_STACK_SIZE);
        2309         [ #  # ]:          0 :     if (it->parent_stack == NULL) {
        2310                 :          0 :         Py_DECREF(it);
        2311                 :          0 :         PyErr_NoMemory();
        2312                 :          0 :         return NULL;
        2313                 :            :     }
        2314                 :          0 :     it->parent_stack_used = 0;
        2315                 :          0 :     it->parent_stack_size = INIT_PARENT_STACK_SIZE;
        2316                 :            :
        2317                 :          0 :     PyObject_GC_Track(it);
        2318                 :            :
        2319                 :          0 :     return (PyObject *)it;
        2320                 :            : }
        2321                 :            :
        2322                 :            :
        2323                 :            : /* ==================================================================== */
        2324                 :            : /* the tree builder type */
        2325                 :            :
        2326                 :            : typedef struct {
        2327                 :            :     PyObject_HEAD
        2328                 :            :
        2329                 :            :     PyObject *root; /* root node (first created node) */
        2330                 :            :
        2331                 :            :     PyObject *this; /* current node */
        2332                 :            :     PyObject *last; /* most recently created node */
        2333                 :            :     PyObject *last_for_tail; /* most recently created node that takes a tail */
        2334                 :            :
        2335                 :            :     PyObject *data; /* data collector (string or list), or NULL */
        2336                 :            :
        2337                 :            :     PyObject *stack; /* element stack */
        2338                 :            :     Py_ssize_t index; /* current stack size (0 means empty) */
        2339                 :            :
        2340                 :            :     PyObject *element_factory;
        2341                 :            :     PyObject *comment_factory;
        2342                 :            :     PyObject *pi_factory;
        2343                 :            :
        2344                 :            :     /* element tracing */
        2345                 :            :     PyObject *events_append; /* the append method of the list of events, or NULL */
        2346                 :            :     PyObject *start_event_obj; /* event objects (NULL to ignore) */
        2347                 :            :     PyObject *end_event_obj;
        2348                 :            :     PyObject *start_ns_event_obj;
        2349                 :            :     PyObject *end_ns_event_obj;
        2350                 :            :     PyObject *comment_event_obj;
        2351                 :            :     PyObject *pi_event_obj;
        2352                 :            :
        2353                 :            :     char insert_comments;
        2354                 :            :     char insert_pis;
        2355                 :            :     elementtreestate *state;
        2356                 :            : } TreeBuilderObject;
        2357                 :            :
        2358                 :            : #define TreeBuilder_CheckExact(st, op) Py_IS_TYPE((op), (st)->TreeBuilder_Type)
        2359                 :            :
        2360                 :            : /* -------------------------------------------------------------------- */
        2361                 :            : /* constructor and destructor */
        2362                 :            :
        2363                 :            : static PyObject *
        2364                 :          0 : treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        2365                 :            : {
        2366                 :          0 :     TreeBuilderObject *t = (TreeBuilderObject *)type->tp_alloc(type, 0);
        2367         [ #  # ]:          0 :     if (t != NULL) {
        2368                 :          0 :         t->root = NULL;
        2369                 :          0 :         t->this = Py_NewRef(Py_None);
        2370                 :          0 :         t->last = Py_NewRef(Py_None);
        2371                 :          0 :         t->data = NULL;
        2372                 :          0 :         t->element_factory = NULL;
        2373                 :          0 :         t->comment_factory = NULL;
        2374                 :          0 :         t->pi_factory = NULL;
        2375                 :          0 :         t->stack = PyList_New(20);
        2376         [ #  # ]:          0 :         if (!t->stack) {
        2377                 :          0 :             Py_DECREF(t->this);
        2378                 :          0 :             Py_DECREF(t->last);
        2379                 :          0 :             Py_DECREF((PyObject *) t);
        2380                 :          0 :             return NULL;
        2381                 :            :         }
        2382                 :          0 :         t->index = 0;
        2383                 :            :
        2384                 :          0 :         t->events_append = NULL;
        2385                 :          0 :         t->start_event_obj = t->end_event_obj = NULL;
        2386                 :          0 :         t->start_ns_event_obj = t->end_ns_event_obj = NULL;
        2387                 :          0 :         t->comment_event_obj = t->pi_event_obj = NULL;
        2388                 :          0 :         t->insert_comments = t->insert_pis = 0;
        2389                 :          0 :         t->state = get_elementtree_state_by_type(type);
        2390                 :            :     }
        2391                 :          0 :     return (PyObject *)t;
        2392                 :            : }
        2393                 :            :
        2394                 :            : /*[clinic input]
        2395                 :            : _elementtree.TreeBuilder.__init__
        2396                 :            :
        2397                 :            :     element_factory: object = None
        2398                 :            :     *
        2399                 :            :     comment_factory: object = None
        2400                 :            :     pi_factory: object = None
        2401                 :            :     insert_comments: bool = False
        2402                 :            :     insert_pis: bool = False
        2403                 :            :
        2404                 :            : [clinic start generated code]*/
        2405                 :            :
        2406                 :            : static int
        2407                 :          0 : _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self,
        2408                 :            :                                        PyObject *element_factory,
        2409                 :            :                                        PyObject *comment_factory,
        2410                 :            :                                        PyObject *pi_factory,
        2411                 :            :                                        int insert_comments, int insert_pis)
        2412                 :            : /*[clinic end generated code: output=8571d4dcadfdf952 input=ae98a94df20b5cc3]*/
        2413                 :            : {
        2414         [ #  # ]:          0 :     if (element_factory != Py_None) {
        2415                 :          0 :         Py_XSETREF(self->element_factory, Py_NewRef(element_factory));
        2416                 :            :     } else {
        2417         [ #  # ]:          0 :         Py_CLEAR(self->element_factory);
        2418                 :            :     }
        2419                 :            :
        2420         [ #  # ]:          0 :     if (comment_factory == Py_None) {
        2421                 :          0 :         elementtreestate *st = self->state;
        2422                 :          0 :         comment_factory = st->comment_factory;
        2423                 :            :     }
        2424         [ #  # ]:          0 :     if (comment_factory) {
        2425                 :          0 :         Py_XSETREF(self->comment_factory, Py_NewRef(comment_factory));
        2426                 :          0 :         self->insert_comments = insert_comments;
        2427                 :            :     } else {
        2428         [ #  # ]:          0 :         Py_CLEAR(self->comment_factory);
        2429                 :          0 :         self->insert_comments = 0;
        2430                 :            :     }
        2431                 :            :
        2432         [ #  # ]:          0 :     if (pi_factory == Py_None) {
        2433                 :          0 :         elementtreestate *st = self->state;
        2434                 :          0 :         pi_factory = st->pi_factory;
        2435                 :            :     }
        2436         [ #  # ]:          0 :     if (pi_factory) {
        2437                 :          0 :         Py_XSETREF(self->pi_factory, Py_NewRef(pi_factory));
        2438                 :          0 :         self->insert_pis = insert_pis;
        2439                 :            :     } else {
        2440         [ #  # ]:          0 :         Py_CLEAR(self->pi_factory);
        2441                 :          0 :         self->insert_pis = 0;
        2442                 :            :     }
        2443                 :            :
        2444                 :          0 :     return 0;
        2445                 :            : }
        2446                 :            :
        2447                 :            : static int
        2448                 :          0 : treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg)
        2449                 :            : {
        2450   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(self));
        2451   [ #  #  #  # ]:          0 :     Py_VISIT(self->pi_event_obj);
        2452   [ #  #  #  # ]:          0 :     Py_VISIT(self->comment_event_obj);
        2453   [ #  #  #  # ]:          0 :     Py_VISIT(self->end_ns_event_obj);
        2454   [ #  #  #  # ]:          0 :     Py_VISIT(self->start_ns_event_obj);
        2455   [ #  #  #  # ]:          0 :     Py_VISIT(self->end_event_obj);
        2456   [ #  #  #  # ]:          0 :     Py_VISIT(self->start_event_obj);
        2457   [ #  #  #  # ]:          0 :     Py_VISIT(self->events_append);
        2458   [ #  #  #  # ]:          0 :     Py_VISIT(self->root);
        2459   [ #  #  #  # ]:          0 :     Py_VISIT(self->this);
        2460   [ #  #  #  # ]:          0 :     Py_VISIT(self->last);
        2461   [ #  #  #  # ]:          0 :     Py_VISIT(self->last_for_tail);
        2462   [ #  #  #  # ]:          0 :     Py_VISIT(self->data);
        2463   [ #  #  #  # ]:          0 :     Py_VISIT(self->stack);
        2464   [ #  #  #  # ]:          0 :     Py_VISIT(self->pi_factory);
        2465   [ #  #  #  # ]:          0 :     Py_VISIT(self->comment_factory);
        2466   [ #  #  #  # ]:          0 :     Py_VISIT(self->element_factory);
        2467                 :          0 :     return 0;
        2468                 :            : }
        2469                 :            :
        2470                 :            : static int
        2471                 :          0 : treebuilder_gc_clear(TreeBuilderObject *self)
        2472                 :            : {
        2473         [ #  # ]:          0 :     Py_CLEAR(self->pi_event_obj);
        2474         [ #  # ]:          0 :     Py_CLEAR(self->comment_event_obj);
        2475         [ #  # ]:          0 :     Py_CLEAR(self->end_ns_event_obj);
        2476         [ #  # ]:          0 :     Py_CLEAR(self->start_ns_event_obj);
        2477         [ #  # ]:          0 :     Py_CLEAR(self->end_event_obj);
        2478         [ #  # ]:          0 :     Py_CLEAR(self->start_event_obj);
        2479         [ #  # ]:          0 :     Py_CLEAR(self->events_append);
        2480         [ #  # ]:          0 :     Py_CLEAR(self->stack);
        2481         [ #  # ]:          0 :     Py_CLEAR(self->data);
        2482         [ #  # ]:          0 :     Py_CLEAR(self->last);
        2483         [ #  # ]:          0 :     Py_CLEAR(self->last_for_tail);
        2484         [ #  # ]:          0 :     Py_CLEAR(self->this);
        2485         [ #  # ]:          0 :     Py_CLEAR(self->pi_factory);
        2486         [ #  # ]:          0 :     Py_CLEAR(self->comment_factory);
        2487         [ #  # ]:          0 :     Py_CLEAR(self->element_factory);
        2488         [ #  # ]:          0 :     Py_CLEAR(self->root);
        2489                 :          0 :     return 0;
        2490                 :            : }
        2491                 :            :
        2492                 :            : static void
        2493                 :          0 : treebuilder_dealloc(TreeBuilderObject *self)
        2494                 :            : {
        2495                 :          0 :     PyTypeObject *tp = Py_TYPE(self);
        2496                 :          0 :     PyObject_GC_UnTrack(self);
        2497                 :          0 :     treebuilder_gc_clear(self);
        2498                 :          0 :     tp->tp_free(self);
        2499                 :          0 :     Py_DECREF(tp);
        2500                 :          0 : }
        2501                 :            :
        2502                 :            : /* -------------------------------------------------------------------- */
        2503                 :            : /* helpers for handling of arbitrary element-like objects */
        2504                 :            :
        2505                 :            : /*[clinic input]
        2506                 :            : _elementtree._set_factories
        2507                 :            :
        2508                 :            :     comment_factory: object
        2509                 :            :     pi_factory: object
        2510                 :            :     /
        2511                 :            :
        2512                 :            : Change the factories used to create comments and processing instructions.
        2513                 :            :
        2514                 :            : For internal use only.
        2515                 :            : [clinic start generated code]*/
        2516                 :            :
        2517                 :            : static PyObject *
        2518                 :          0 : _elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory,
        2519                 :            :                                  PyObject *pi_factory)
        2520                 :            : /*[clinic end generated code: output=813b408adee26535 input=99d17627aea7fb3b]*/
        2521                 :            : {
        2522                 :          0 :     elementtreestate *st = get_elementtree_state(module);
        2523                 :            :     PyObject *old;
        2524                 :            :
        2525   [ #  #  #  # ]:          0 :     if (!PyCallable_Check(comment_factory) && comment_factory != Py_None) {
        2526                 :          0 :         PyErr_Format(PyExc_TypeError, "Comment factory must be callable, not %.100s",
        2527                 :          0 :                      Py_TYPE(comment_factory)->tp_name);
        2528                 :          0 :         return NULL;
        2529                 :            :     }
        2530   [ #  #  #  # ]:          0 :     if (!PyCallable_Check(pi_factory) && pi_factory != Py_None) {
        2531                 :          0 :         PyErr_Format(PyExc_TypeError, "PI factory must be callable, not %.100s",
        2532                 :          0 :                      Py_TYPE(pi_factory)->tp_name);
        2533                 :          0 :         return NULL;
        2534                 :            :     }
        2535                 :            :
        2536                 :          0 :     old = PyTuple_Pack(2,
        2537         [ #  # ]:          0 :         st->comment_factory ? st->comment_factory : Py_None,
        2538         [ #  # ]:          0 :         st->pi_factory ? st->pi_factory : Py_None);
        2539                 :            :
        2540         [ #  # ]:          0 :     if (comment_factory == Py_None) {
        2541         [ #  # ]:          0 :         Py_CLEAR(st->comment_factory);
        2542                 :            :     } else {
        2543                 :          0 :         Py_XSETREF(st->comment_factory, Py_NewRef(comment_factory));
        2544                 :            :     }
        2545         [ #  # ]:          0 :     if (pi_factory == Py_None) {
        2546         [ #  # ]:          0 :         Py_CLEAR(st->pi_factory);
        2547                 :            :     } else {
        2548                 :          0 :         Py_XSETREF(st->pi_factory, Py_NewRef(pi_factory));
        2549                 :            :     }
        2550                 :            :
        2551                 :          0 :     return old;
        2552                 :            : }
        2553                 :            :
        2554                 :            : static int
        2555                 :          0 : treebuilder_extend_element_text_or_tail(elementtreestate *st, PyObject *element,
        2556                 :            :                                         PyObject **data, PyObject **dest,
        2557                 :            :                                         PyObject *name)
        2558                 :            : {
        2559                 :            :     /* Fast paths for the "almost always" cases. */
        2560         [ #  # ]:          0 :     if (Element_CheckExact(st, element)) {
        2561                 :          0 :         PyObject *dest_obj = JOIN_OBJ(*dest);
        2562         [ #  # ]:          0 :         if (dest_obj == Py_None) {
        2563                 :          0 :             *dest = JOIN_SET(*data, PyList_CheckExact(*data));
        2564                 :          0 :             *data = NULL;
        2565                 :          0 :             Py_DECREF(dest_obj);
        2566                 :          0 :             return 0;
        2567                 :            :         }
        2568         [ #  # ]:          0 :         else if (JOIN_GET(*dest)) {
        2569         [ #  # ]:          0 :             if (PyList_SetSlice(dest_obj, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, *data) < 0) {
        2570                 :          0 :                 return -1;
        2571                 :            :             }
        2572         [ #  # ]:          0 :             Py_CLEAR(*data);
        2573                 :          0 :             return 0;
        2574                 :            :         }
        2575                 :            :     }
        2576                 :            :
        2577                 :            :     /*  Fallback for the non-Element / non-trivial cases. */
        2578                 :            :     {
        2579                 :            :         int r;
        2580                 :            :         PyObject* joined;
        2581                 :          0 :         PyObject* previous = PyObject_GetAttr(element, name);
        2582         [ #  # ]:          0 :         if (!previous)
        2583                 :          0 :             return -1;
        2584                 :          0 :         joined = list_join(*data);
        2585         [ #  # ]:          0 :         if (!joined) {
        2586                 :          0 :             Py_DECREF(previous);
        2587                 :          0 :             return -1;
        2588                 :            :         }
        2589         [ #  # ]:          0 :         if (previous != Py_None) {
        2590                 :          0 :             PyObject *tmp = PyNumber_Add(previous, joined);
        2591                 :          0 :             Py_DECREF(joined);
        2592                 :          0 :             Py_DECREF(previous);
        2593         [ #  # ]:          0 :             if (!tmp)
        2594                 :          0 :                 return -1;
        2595                 :          0 :             joined = tmp;
        2596                 :            :         } else {
        2597                 :          0 :             Py_DECREF(previous);
        2598                 :            :         }
        2599                 :            :
        2600                 :          0 :         r = PyObject_SetAttr(element, name, joined);
        2601                 :          0 :         Py_DECREF(joined);
        2602         [ #  # ]:          0 :         if (r < 0)
        2603                 :          0 :             return -1;
        2604         [ #  # ]:          0 :         Py_CLEAR(*data);
        2605                 :          0 :         return 0;
        2606                 :            :     }
        2607                 :            : }
        2608                 :            :
        2609                 :            : LOCAL(int)
        2610                 :          0 : treebuilder_flush_data(TreeBuilderObject* self)
        2611                 :            : {
        2612         [ #  # ]:          0 :     if (!self->data) {
        2613                 :          0 :         return 0;
        2614                 :            :     }
        2615                 :          0 :     elementtreestate *st = self->state;
        2616         [ #  # ]:          0 :     if (!self->last_for_tail) {
        2617                 :          0 :         PyObject *element = self->last;
        2618                 :          0 :         return treebuilder_extend_element_text_or_tail(
        2619                 :            :                 st, element, &self->data,
        2620                 :            :                 &((ElementObject *) element)->text, st->str_text);
        2621                 :            :     }
        2622                 :            :     else {
        2623                 :          0 :         PyObject *element = self->last_for_tail;
        2624                 :          0 :         return treebuilder_extend_element_text_or_tail(
        2625                 :            :                 st, element, &self->data,
        2626                 :            :                 &((ElementObject *) element)->tail, st->str_tail);
        2627                 :            :     }
        2628                 :            : }
        2629                 :            :
        2630                 :            : static int
        2631                 :          0 : treebuilder_add_subelement(elementtreestate *st, PyObject *element,
        2632                 :            :                            PyObject *child)
        2633                 :            : {
        2634         [ #  # ]:          0 :     if (Element_CheckExact(st, element)) {
        2635                 :          0 :         ElementObject *elem = (ElementObject *) element;
        2636                 :          0 :         return element_add_subelement(st, elem, child);
        2637                 :            :     }
        2638                 :            :     else {
        2639                 :            :         PyObject *res;
        2640                 :          0 :         res = PyObject_CallMethodOneArg(element, st->str_append, child);
        2641         [ #  # ]:          0 :         if (res == NULL)
        2642                 :          0 :             return -1;
        2643                 :          0 :         Py_DECREF(res);
        2644                 :          0 :         return 0;
        2645                 :            :     }
        2646                 :            : }
        2647                 :            :
        2648                 :            : LOCAL(int)
        2649                 :          0 : treebuilder_append_event(TreeBuilderObject *self, PyObject *action,
        2650                 :            :                          PyObject *node)
        2651                 :            : {
        2652         [ #  # ]:          0 :     if (action != NULL) {
        2653                 :            :         PyObject *res;
        2654                 :          0 :         PyObject *event = PyTuple_Pack(2, action, node);
        2655         [ #  # ]:          0 :         if (event == NULL)
        2656                 :          0 :             return -1;
        2657                 :          0 :         res = PyObject_CallOneArg(self->events_append, event);
        2658                 :          0 :         Py_DECREF(event);
        2659         [ #  # ]:          0 :         if (res == NULL)
        2660                 :          0 :             return -1;
        2661                 :          0 :         Py_DECREF(res);
        2662                 :            :     }
        2663                 :          0 :     return 0;
        2664                 :            : }
        2665                 :            :
        2666                 :            : /* -------------------------------------------------------------------- */
        2667                 :            : /* handlers */
        2668                 :            :
        2669                 :            : LOCAL(PyObject*)
        2670                 :          0 : treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
        2671                 :            :                          PyObject* attrib)
        2672                 :            : {
        2673                 :            :     PyObject* node;
        2674                 :            :     PyObject* this;
        2675                 :          0 :     elementtreestate *st = self->state;
        2676                 :            :
        2677         [ #  # ]:          0 :     if (treebuilder_flush_data(self) < 0) {
        2678                 :          0 :         return NULL;
        2679                 :            :     }
        2680                 :            :
        2681         [ #  # ]:          0 :     if (!self->element_factory) {
        2682                 :          0 :         node = create_new_element(st, tag, attrib);
        2683                 :            :     }
        2684         [ #  # ]:          0 :     else if (attrib == NULL) {
        2685                 :          0 :         attrib = PyDict_New();
        2686         [ #  # ]:          0 :         if (!attrib)
        2687                 :          0 :             return NULL;
        2688                 :          0 :         node = PyObject_CallFunctionObjArgs(self->element_factory,
        2689                 :            :                                             tag, attrib, NULL);
        2690                 :          0 :         Py_DECREF(attrib);
        2691                 :            :     }
        2692                 :            :     else {
        2693                 :          0 :         node = PyObject_CallFunctionObjArgs(self->element_factory,
        2694                 :            :                                             tag, attrib, NULL);
        2695                 :            :     }
        2696         [ #  # ]:          0 :     if (!node) {
        2697                 :          0 :         return NULL;
        2698                 :            :     }
        2699                 :            :
        2700                 :          0 :     this = self->this;
        2701         [ #  # ]:          0 :     Py_CLEAR(self->last_for_tail);
        2702                 :            :
        2703         [ #  # ]:          0 :     if (this != Py_None) {
        2704         [ #  # ]:          0 :         if (treebuilder_add_subelement(st, this, node) < 0) {
        2705                 :          0 :             goto error;
        2706                 :            :         }
        2707                 :            :     } else {
        2708         [ #  # ]:          0 :         if (self->root) {
        2709                 :          0 :             PyErr_SetString(
        2710                 :            :                 st->parseerror_obj,
        2711                 :            :                 "multiple elements on top level"
        2712                 :            :                 );
        2713                 :          0 :             goto error;
        2714                 :            :         }
        2715                 :          0 :         self->root = Py_NewRef(node);
        2716                 :            :     }
        2717                 :            :
        2718         [ #  # ]:          0 :     if (self->index < PyList_GET_SIZE(self->stack)) {
        2719         [ #  # ]:          0 :         if (PyList_SetItem(self->stack, self->index, this) < 0)
        2720                 :          0 :             goto error;
        2721                 :          0 :         Py_INCREF(this);
        2722                 :            :     } else {
        2723         [ #  # ]:          0 :         if (PyList_Append(self->stack, this) < 0)
        2724                 :          0 :             goto error;
        2725                 :            :     }
        2726                 :          0 :     self->index++;
        2727                 :            :
        2728                 :          0 :     Py_SETREF(self->this, Py_NewRef(node));
        2729                 :          0 :     Py_SETREF(self->last, Py_NewRef(node));
        2730                 :            :
        2731         [ #  # ]:          0 :     if (treebuilder_append_event(self, self->start_event_obj, node) < 0)
        2732                 :          0 :         goto error;
        2733                 :            :
        2734                 :          0 :     return node;
        2735                 :            :
        2736                 :          0 :   error:
        2737                 :          0 :     Py_DECREF(node);
        2738                 :          0 :     return NULL;
        2739                 :            : }
        2740                 :            :
        2741                 :            : LOCAL(PyObject*)
        2742                 :          0 : treebuilder_handle_data(TreeBuilderObject* self, PyObject* data)
        2743                 :            : {
        2744         [ #  # ]:          0 :     if (!self->data) {
        2745         [ #  # ]:          0 :         if (self->last == Py_None) {
        2746                 :            :             /* ignore calls to data before the first call to start */
        2747                 :          0 :             Py_RETURN_NONE;
        2748                 :            :         }
        2749                 :            :         /* store the first item as is */
        2750                 :          0 :         self->data = Py_NewRef(data);
        2751                 :            :     } else {
        2752                 :            :         /* more than one item; use a list to collect items */
        2753   [ #  #  #  #  :          0 :         if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 &&
                       #  # ]
        2754         [ #  # ]:          0 :             PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) {
        2755                 :            :             /* XXX this code path unused in Python 3? */
        2756                 :            :             /* expat often generates single character data sections; handle
        2757                 :            :                the most common case by resizing the existing string... */
        2758                 :          0 :             Py_ssize_t size = PyBytes_GET_SIZE(self->data);
        2759         [ #  # ]:          0 :             if (_PyBytes_Resize(&self->data, size + 1) < 0)
        2760                 :          0 :                 return NULL;
        2761                 :          0 :             PyBytes_AS_STRING(self->data)[size] = PyBytes_AS_STRING(data)[0];
        2762         [ #  # ]:          0 :         } else if (PyList_CheckExact(self->data)) {
        2763         [ #  # ]:          0 :             if (PyList_Append(self->data, data) < 0)
        2764                 :          0 :                 return NULL;
        2765                 :            :         } else {
        2766                 :          0 :             PyObject* list = PyList_New(2);
        2767         [ #  # ]:          0 :             if (!list)
        2768                 :          0 :                 return NULL;
        2769                 :          0 :             PyList_SET_ITEM(list, 0, Py_NewRef(self->data));
        2770                 :          0 :             PyList_SET_ITEM(list, 1, Py_NewRef(data));
        2771                 :          0 :             Py_SETREF(self->data, list);
        2772                 :            :         }
        2773                 :            :     }
        2774                 :            :
        2775                 :          0 :     Py_RETURN_NONE;
        2776                 :            : }
        2777                 :            :
        2778                 :            : LOCAL(PyObject*)
        2779                 :          0 : treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
        2780                 :            : {
        2781                 :            :     PyObject* item;
        2782                 :            :
        2783         [ #  # ]:          0 :     if (treebuilder_flush_data(self) < 0) {
        2784                 :          0 :         return NULL;
        2785                 :            :     }
        2786                 :            :
        2787         [ #  # ]:          0 :     if (self->index == 0) {
        2788                 :          0 :         PyErr_SetString(
        2789                 :            :             PyExc_IndexError,
        2790                 :            :             "pop from empty stack"
        2791                 :            :             );
        2792                 :          0 :         return NULL;
        2793                 :            :     }
        2794                 :            :
        2795                 :          0 :     item = self->last;
        2796                 :          0 :     self->last = Py_NewRef(self->this);
        2797                 :          0 :     Py_XSETREF(self->last_for_tail, self->last);
        2798                 :          0 :     self->index--;
        2799                 :          0 :     self->this = Py_NewRef(PyList_GET_ITEM(self->stack, self->index));
        2800                 :          0 :     Py_DECREF(item);
        2801                 :            :
        2802         [ #  # ]:          0 :     if (treebuilder_append_event(self, self->end_event_obj, self->last) < 0)
        2803                 :          0 :         return NULL;
        2804                 :            :
        2805                 :          0 :     return Py_NewRef(self->last);
        2806                 :            : }
        2807                 :            :
        2808                 :            : LOCAL(PyObject*)
        2809                 :          0 : treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text)
        2810                 :            : {
        2811                 :            :     PyObject* comment;
        2812                 :            :     PyObject* this;
        2813                 :            :
        2814         [ #  # ]:          0 :     if (treebuilder_flush_data(self) < 0) {
        2815                 :          0 :         return NULL;
        2816                 :            :     }
        2817                 :            :
        2818         [ #  # ]:          0 :     if (self->comment_factory) {
        2819                 :          0 :         comment = PyObject_CallOneArg(self->comment_factory, text);
        2820         [ #  # ]:          0 :         if (!comment)
        2821                 :          0 :             return NULL;
        2822                 :            :
        2823                 :          0 :         this = self->this;
        2824   [ #  #  #  # ]:          0 :         if (self->insert_comments && this != Py_None) {
        2825         [ #  # ]:          0 :             if (treebuilder_add_subelement(self->state, this, comment) < 0) {
        2826                 :          0 :                 goto error;
        2827                 :            :             }
        2828                 :          0 :             Py_XSETREF(self->last_for_tail, Py_NewRef(comment));
        2829                 :            :         }
        2830                 :            :     } else {
        2831                 :          0 :         comment = Py_NewRef(text);
        2832                 :            :     }
        2833                 :            :
        2834   [ #  #  #  # ]:          0 :     if (self->events_append && self->comment_event_obj) {
        2835         [ #  # ]:          0 :         if (treebuilder_append_event(self, self->comment_event_obj, comment) < 0)
        2836                 :          0 :             goto error;
        2837                 :            :     }
        2838                 :            :
        2839                 :          0 :     return comment;
        2840                 :            :
        2841                 :          0 :   error:
        2842                 :          0 :     Py_DECREF(comment);
        2843                 :          0 :     return NULL;
        2844                 :            : }
        2845                 :            :
        2846                 :            : LOCAL(PyObject*)
        2847                 :          0 : treebuilder_handle_pi(TreeBuilderObject* self, PyObject* target, PyObject* text)
        2848                 :            : {
        2849                 :            :     PyObject* pi;
        2850                 :            :     PyObject* this;
        2851                 :          0 :     PyObject* stack[2] = {target, text};
        2852                 :            :
        2853         [ #  # ]:          0 :     if (treebuilder_flush_data(self) < 0) {
        2854                 :          0 :         return NULL;
        2855                 :            :     }
        2856                 :            :
        2857         [ #  # ]:          0 :     if (self->pi_factory) {
        2858                 :          0 :         pi = _PyObject_FastCall(self->pi_factory, stack, 2);
        2859         [ #  # ]:          0 :         if (!pi) {
        2860                 :          0 :             return NULL;
        2861                 :            :         }
        2862                 :            :
        2863                 :          0 :         this = self->this;
        2864   [ #  #  #  # ]:          0 :         if (self->insert_pis && this != Py_None) {
        2865         [ #  # ]:          0 :             if (treebuilder_add_subelement(self->state, this, pi) < 0) {
        2866                 :          0 :                 goto error;
        2867                 :            :             }
        2868                 :          0 :             Py_XSETREF(self->last_for_tail, Py_NewRef(pi));
        2869                 :            :         }
        2870                 :            :     } else {
        2871                 :          0 :         pi = PyTuple_Pack(2, target, text);
        2872         [ #  # ]:          0 :         if (!pi) {
        2873                 :          0 :             return NULL;
        2874                 :            :         }
        2875                 :            :     }
        2876                 :            :
        2877   [ #  #  #  # ]:          0 :     if (self->events_append && self->pi_event_obj) {
        2878         [ #  # ]:          0 :         if (treebuilder_append_event(self, self->pi_event_obj, pi) < 0)
        2879                 :          0 :             goto error;
        2880                 :            :     }
        2881                 :            :
        2882                 :          0 :     return pi;
        2883                 :            :
        2884                 :          0 :   error:
        2885                 :          0 :     Py_DECREF(pi);
        2886                 :          0 :     return NULL;
        2887                 :            : }
        2888                 :            :
        2889                 :            : LOCAL(PyObject*)
        2890                 :          0 : treebuilder_handle_start_ns(TreeBuilderObject* self, PyObject* prefix, PyObject* uri)
        2891                 :            : {
        2892                 :            :     PyObject* parcel;
        2893                 :            :
        2894   [ #  #  #  # ]:          0 :     if (self->events_append && self->start_ns_event_obj) {
        2895                 :          0 :         parcel = PyTuple_Pack(2, prefix, uri);
        2896         [ #  # ]:          0 :         if (!parcel) {
        2897                 :          0 :             return NULL;
        2898                 :            :         }
        2899                 :            :
        2900         [ #  # ]:          0 :         if (treebuilder_append_event(self, self->start_ns_event_obj, parcel) < 0) {
        2901                 :          0 :             Py_DECREF(parcel);
        2902                 :          0 :             return NULL;
        2903                 :            :         }
        2904                 :          0 :         Py_DECREF(parcel);
        2905                 :            :     }
        2906                 :            :
        2907                 :          0 :     Py_RETURN_NONE;
        2908                 :            : }
        2909                 :            :
        2910                 :            : LOCAL(PyObject*)
        2911                 :          0 : treebuilder_handle_end_ns(TreeBuilderObject* self, PyObject* prefix)
        2912                 :            : {
        2913   [ #  #  #  # ]:          0 :     if (self->events_append && self->end_ns_event_obj) {
        2914         [ #  # ]:          0 :         if (treebuilder_append_event(self, self->end_ns_event_obj, prefix) < 0) {
        2915                 :          0 :             return NULL;
        2916                 :            :         }
        2917                 :            :     }
        2918                 :            :
        2919                 :          0 :     Py_RETURN_NONE;
        2920                 :            : }
        2921                 :            :
        2922                 :            : /* -------------------------------------------------------------------- */
        2923                 :            : /* methods (in alphabetical order) */
        2924                 :            :
        2925                 :            : /*[clinic input]
        2926                 :            : _elementtree.TreeBuilder.data
        2927                 :            :
        2928                 :            :     data: object
        2929                 :            :     /
        2930                 :            :
        2931                 :            : [clinic start generated code]*/
        2932                 :            :
        2933                 :            : static PyObject *
        2934                 :          0 : _elementtree_TreeBuilder_data(TreeBuilderObject *self, PyObject *data)
        2935                 :            : /*[clinic end generated code: output=69144c7100795bb2 input=a0540c532b284d29]*/
        2936                 :            : {
        2937                 :          0 :     return treebuilder_handle_data(self, data);
        2938                 :            : }
        2939                 :            :
        2940                 :            : /*[clinic input]
        2941                 :            : _elementtree.TreeBuilder.end
        2942                 :            :
        2943                 :            :     tag: object
        2944                 :            :     /
        2945                 :            :
        2946                 :            : [clinic start generated code]*/
        2947                 :            :
        2948                 :            : static PyObject *
        2949                 :          0 : _elementtree_TreeBuilder_end(TreeBuilderObject *self, PyObject *tag)
        2950                 :            : /*[clinic end generated code: output=9a98727cc691cd9d input=22dc3674236f5745]*/
        2951                 :            : {
        2952                 :          0 :     return treebuilder_handle_end(self, tag);
        2953                 :            : }
        2954                 :            :
        2955                 :            : /*[clinic input]
        2956                 :            : _elementtree.TreeBuilder.comment
        2957                 :            :
        2958                 :            :     text: object
        2959                 :            :     /
        2960                 :            :
        2961                 :            : [clinic start generated code]*/
        2962                 :            :
        2963                 :            : static PyObject *
        2964                 :          0 : _elementtree_TreeBuilder_comment(TreeBuilderObject *self, PyObject *text)
        2965                 :            : /*[clinic end generated code: output=22835be41deeaa27 input=47e7ebc48ed01dfa]*/
        2966                 :            : {
        2967                 :          0 :     return treebuilder_handle_comment(self, text);
        2968                 :            : }
        2969                 :            :
        2970                 :            : /*[clinic input]
        2971                 :            : _elementtree.TreeBuilder.pi
        2972                 :            :
        2973                 :            :     target: object
        2974                 :            :     text: object = None
        2975                 :            :     /
        2976                 :            :
        2977                 :            : [clinic start generated code]*/
        2978                 :            :
        2979                 :            : static PyObject *
        2980                 :          0 : _elementtree_TreeBuilder_pi_impl(TreeBuilderObject *self, PyObject *target,
        2981                 :            :                                  PyObject *text)
        2982                 :            : /*[clinic end generated code: output=21eb95ec9d04d1d9 input=349342bd79c35570]*/
        2983                 :            : {
        2984                 :          0 :     return treebuilder_handle_pi(self, target, text);
        2985                 :            : }
        2986                 :            :
        2987                 :            : LOCAL(PyObject*)
        2988                 :          0 : treebuilder_done(TreeBuilderObject* self)
        2989                 :            : {
        2990                 :            :     PyObject* res;
        2991                 :            :
        2992                 :            :     /* FIXME: check stack size? */
        2993                 :            :
        2994         [ #  # ]:          0 :     if (self->root)
        2995                 :          0 :         res = self->root;
        2996                 :            :     else
        2997                 :          0 :         res = Py_None;
        2998                 :            :
        2999                 :          0 :     return Py_NewRef(res);
        3000                 :            : }
        3001                 :            :
        3002                 :            : /*[clinic input]
        3003                 :            : _elementtree.TreeBuilder.close
        3004                 :            :
        3005                 :            : [clinic start generated code]*/
        3006                 :            :
        3007                 :            : static PyObject *
        3008                 :          0 : _elementtree_TreeBuilder_close_impl(TreeBuilderObject *self)
        3009                 :            : /*[clinic end generated code: output=b441fee3202f61ee input=f7c9c65dc718de14]*/
        3010                 :            : {
        3011                 :          0 :     return treebuilder_done(self);
        3012                 :            : }
        3013                 :            :
        3014                 :            : /*[clinic input]
        3015                 :            : _elementtree.TreeBuilder.start
        3016                 :            :
        3017                 :            :     tag: object
        3018                 :            :     attrs: object(subclass_of='&PyDict_Type')
        3019                 :            :     /
        3020                 :            :
        3021                 :            : [clinic start generated code]*/
        3022                 :            :
        3023                 :            : static PyObject *
        3024                 :          0 : _elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag,
        3025                 :            :                                     PyObject *attrs)
        3026                 :            : /*[clinic end generated code: output=e7e9dc2861349411 input=7288e9e38e63b2b6]*/
        3027                 :            : {
        3028                 :          0 :     return treebuilder_handle_start(self, tag, attrs);
        3029                 :            : }
        3030                 :            :
        3031                 :            : /* ==================================================================== */
        3032                 :            : /* the expat interface */
        3033                 :            :
        3034                 :            : #include "expat.h"
        3035                 :            : #include "pyexpat.h"
        3036                 :            :
        3037                 :            : /* The PyExpat_CAPI structure is an immutable dispatch table, so it can be
        3038                 :            :  * cached globally without being in per-module state.
        3039                 :            :  */
        3040                 :            : static struct PyExpat_CAPI *expat_capi;
        3041                 :            : #define EXPAT(func) (expat_capi->func)
        3042                 :            :
        3043                 :            : static XML_Memory_Handling_Suite ExpatMemoryHandler = {
        3044                 :            :     PyObject_Malloc, PyObject_Realloc, PyObject_Free};
        3045                 :            :
        3046                 :            : typedef struct {
        3047                 :            :     PyObject_HEAD
        3048                 :            :
        3049                 :            :     XML_Parser parser;
        3050                 :            :
        3051                 :            :     PyObject *target;
        3052                 :            :     PyObject *entity;
        3053                 :            :
        3054                 :            :     PyObject *names;
        3055                 :            :
        3056                 :            :     PyObject *handle_start_ns;
        3057                 :            :     PyObject *handle_end_ns;
        3058                 :            :     PyObject *handle_start;
        3059                 :            :     PyObject *handle_data;
        3060                 :            :     PyObject *handle_end;
        3061                 :            :
        3062                 :            :     PyObject *handle_comment;
        3063                 :            :     PyObject *handle_pi;
        3064                 :            :     PyObject *handle_doctype;
        3065                 :            :
        3066                 :            :     PyObject *handle_close;
        3067                 :            :
        3068                 :            :     elementtreestate *state;
        3069                 :            : } XMLParserObject;
        3070                 :            :
        3071                 :            : /* helpers */
        3072                 :            :
        3073                 :            : LOCAL(PyObject*)
        3074                 :          0 : makeuniversal(XMLParserObject* self, const char* string)
        3075                 :            : {
        3076                 :            :     /* convert a UTF-8 tag/attribute name from the expat parser
        3077                 :            :        to a universal name string */
        3078                 :            :
        3079                 :          0 :     Py_ssize_t size = (Py_ssize_t) strlen(string);
        3080                 :            :     PyObject* key;
        3081                 :            :     PyObject* value;
        3082                 :            :
        3083                 :            :     /* look the 'raw' name up in the names dictionary */
        3084                 :          0 :     key = PyBytes_FromStringAndSize(string, size);
        3085         [ #  # ]:          0 :     if (!key)
        3086                 :          0 :         return NULL;
        3087                 :            :
        3088                 :          0 :     value = Py_XNewRef(PyDict_GetItemWithError(self->names, key));
        3089                 :            :
        3090   [ #  #  #  # ]:          0 :     if (value == NULL && !PyErr_Occurred()) {
        3091                 :            :         /* new name.  convert to universal name, and decode as
        3092                 :            :            necessary */
        3093                 :            :
        3094                 :            :         PyObject* tag;
        3095                 :            :         char* p;
        3096                 :            :         Py_ssize_t i;
        3097                 :            :
        3098                 :            :         /* look for namespace separator */
        3099         [ #  # ]:          0 :         for (i = 0; i < size; i++)
        3100         [ #  # ]:          0 :             if (string[i] == '}')
        3101                 :          0 :                 break;
        3102         [ #  # ]:          0 :         if (i != size) {
        3103                 :            :             /* convert to universal name */
        3104                 :          0 :             tag = PyBytes_FromStringAndSize(NULL, size+1);
        3105         [ #  # ]:          0 :             if (tag == NULL) {
        3106                 :          0 :                 Py_DECREF(key);
        3107                 :          0 :                 return NULL;
        3108                 :            :             }
        3109                 :          0 :             p = PyBytes_AS_STRING(tag);
        3110                 :          0 :             p[0] = '{';
        3111                 :          0 :             memcpy(p+1, string, size);
        3112                 :          0 :             size++;
        3113                 :            :         } else {
        3114                 :            :             /* plain name; use key as tag */
        3115                 :          0 :             tag = Py_NewRef(key);
        3116                 :            :         }
        3117                 :            :
        3118                 :            :         /* decode universal name */
        3119                 :          0 :         p = PyBytes_AS_STRING(tag);
        3120                 :          0 :         value = PyUnicode_DecodeUTF8(p, size, "strict");
        3121                 :          0 :         Py_DECREF(tag);
        3122         [ #  # ]:          0 :         if (!value) {
        3123                 :          0 :             Py_DECREF(key);
        3124                 :          0 :             return NULL;
        3125                 :            :         }
        3126                 :            :
        3127                 :            :         /* add to names dictionary */
        3128         [ #  # ]:          0 :         if (PyDict_SetItem(self->names, key, value) < 0) {
        3129                 :          0 :             Py_DECREF(key);
        3130                 :          0 :             Py_DECREF(value);
        3131                 :          0 :             return NULL;
        3132                 :            :         }
        3133                 :            :     }
        3134                 :            :
        3135                 :          0 :     Py_DECREF(key);
        3136                 :          0 :     return value;
        3137                 :            : }
        3138                 :            :
        3139                 :            : /* Set the ParseError exception with the given parameters.
        3140                 :            :  * If message is not NULL, it's used as the error string. Otherwise, the
        3141                 :            :  * message string is the default for the given error_code.
        3142                 :            : */
        3143                 :            : static void
        3144                 :          0 : expat_set_error(elementtreestate *st, enum XML_Error error_code,
        3145                 :            :                 Py_ssize_t line, Py_ssize_t column, const char *message)
        3146                 :            : {
        3147                 :            :     PyObject *errmsg, *error, *position, *code;
        3148                 :            :
        3149         [ #  # ]:          0 :     errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd",
        3150                 :          0 :                 message ? message : EXPAT(ErrorString)(error_code),
        3151                 :            :                 line, column);
        3152         [ #  # ]:          0 :     if (errmsg == NULL)
        3153                 :          0 :         return;
        3154                 :            :
        3155                 :          0 :     error = PyObject_CallOneArg(st->parseerror_obj, errmsg);
        3156                 :          0 :     Py_DECREF(errmsg);
        3157         [ #  # ]:          0 :     if (!error)
        3158                 :          0 :         return;
        3159                 :            :
        3160                 :            :     /* Add code and position attributes */
        3161                 :          0 :     code = PyLong_FromLong((long)error_code);
        3162         [ #  # ]:          0 :     if (!code) {
        3163                 :          0 :         Py_DECREF(error);
        3164                 :          0 :         return;
        3165                 :            :     }
        3166         [ #  # ]:          0 :     if (PyObject_SetAttrString(error, "code", code) == -1) {
        3167                 :          0 :         Py_DECREF(error);
        3168                 :          0 :         Py_DECREF(code);
        3169                 :          0 :         return;
        3170                 :            :     }
        3171                 :          0 :     Py_DECREF(code);
        3172                 :            :
        3173                 :          0 :     position = Py_BuildValue("(nn)", line, column);
        3174         [ #  # ]:          0 :     if (!position) {
        3175                 :          0 :         Py_DECREF(error);
        3176                 :          0 :         return;
        3177                 :            :     }
        3178         [ #  # ]:          0 :     if (PyObject_SetAttrString(error, "position", position) == -1) {
        3179                 :          0 :         Py_DECREF(error);
        3180                 :          0 :         Py_DECREF(position);
        3181                 :          0 :         return;
        3182                 :            :     }
        3183                 :          0 :     Py_DECREF(position);
        3184                 :            :
        3185                 :          0 :     PyErr_SetObject(st->parseerror_obj, error);
        3186                 :          0 :     Py_DECREF(error);
        3187                 :            : }
        3188                 :            :
        3189                 :            : /* -------------------------------------------------------------------- */
        3190                 :            : /* handlers */
        3191                 :            :
        3192                 :            : static void
        3193                 :          0 : expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
        3194                 :            :                       int data_len)
        3195                 :            : {
        3196                 :            :     PyObject* key;
        3197                 :            :     PyObject* value;
        3198                 :            :     PyObject* res;
        3199                 :            :
        3200   [ #  #  #  # ]:          0 :     if (data_len < 2 || data_in[0] != '&')
        3201                 :          0 :         return;
        3202                 :            :
        3203         [ #  # ]:          0 :     if (PyErr_Occurred())
        3204                 :          0 :         return;
        3205                 :            :
        3206                 :          0 :     key = PyUnicode_DecodeUTF8(data_in + 1, data_len - 2, "strict");
        3207         [ #  # ]:          0 :     if (!key)
        3208                 :          0 :         return;
        3209                 :            :
        3210                 :          0 :     value = PyDict_GetItemWithError(self->entity, key);
        3211                 :            :
        3212                 :          0 :     elementtreestate *st = self->state;
        3213         [ #  # ]:          0 :     if (value) {
        3214         [ #  # ]:          0 :         if (TreeBuilder_CheckExact(st, self->target))
        3215                 :          0 :             res = treebuilder_handle_data(
        3216                 :          0 :                 (TreeBuilderObject*) self->target, value
        3217                 :            :                 );
        3218         [ #  # ]:          0 :         else if (self->handle_data)
        3219                 :          0 :             res = PyObject_CallOneArg(self->handle_data, value);
        3220                 :            :         else
        3221                 :          0 :             res = NULL;
        3222                 :          0 :         Py_XDECREF(res);
        3223         [ #  # ]:          0 :     } else if (!PyErr_Occurred()) {
        3224                 :            :         /* Report the first error, not the last */
        3225                 :          0 :         char message[128] = "undefined entity ";
        3226                 :          0 :         strncat(message, data_in, data_len < 100?data_len:100);
        3227                 :          0 :         expat_set_error(
        3228                 :            :             st,
        3229                 :            :             XML_ERROR_UNDEFINED_ENTITY,
        3230                 :          0 :             EXPAT(GetErrorLineNumber)(self->parser),
        3231                 :          0 :             EXPAT(GetErrorColumnNumber)(self->parser),
        3232                 :            :             message
        3233                 :            :             );
        3234                 :            :     }
        3235                 :            :
        3236                 :          0 :     Py_DECREF(key);
        3237                 :            : }
        3238                 :            :
        3239                 :            : static void
        3240                 :          0 : expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
        3241                 :            :                     const XML_Char **attrib_in)
        3242                 :            : {
        3243                 :            :     PyObject* res;
        3244                 :            :     PyObject* tag;
        3245                 :            :     PyObject* attrib;
        3246                 :            :     int ok;
        3247                 :            :
        3248         [ #  # ]:          0 :     if (PyErr_Occurred())
        3249                 :          0 :         return;
        3250                 :            :
        3251                 :            :     /* tag name */
        3252                 :          0 :     tag = makeuniversal(self, tag_in);
        3253         [ #  # ]:          0 :     if (!tag)
        3254                 :          0 :         return; /* parser will look for errors */
        3255                 :            :
        3256                 :            :     /* attributes */
        3257         [ #  # ]:          0 :     if (attrib_in[0]) {
        3258                 :          0 :         attrib = PyDict_New();
        3259         [ #  # ]:          0 :         if (!attrib) {
        3260                 :          0 :             Py_DECREF(tag);
        3261                 :          0 :             return;
        3262                 :            :         }
        3263   [ #  #  #  # ]:          0 :         while (attrib_in[0] && attrib_in[1]) {
        3264                 :          0 :             PyObject* key = makeuniversal(self, attrib_in[0]);
        3265                 :          0 :             PyObject* value = PyUnicode_DecodeUTF8(attrib_in[1], strlen(attrib_in[1]), "strict");
        3266   [ #  #  #  # ]:          0 :             if (!key || !value) {
        3267                 :          0 :                 Py_XDECREF(value);
        3268                 :          0 :                 Py_XDECREF(key);
        3269                 :          0 :                 Py_DECREF(attrib);
        3270                 :          0 :                 Py_DECREF(tag);
        3271                 :          0 :                 return;
        3272                 :            :             }
        3273                 :          0 :             ok = PyDict_SetItem(attrib, key, value);
        3274                 :          0 :             Py_DECREF(value);
        3275                 :          0 :             Py_DECREF(key);
        3276         [ #  # ]:          0 :             if (ok < 0) {
        3277                 :          0 :                 Py_DECREF(attrib);
        3278                 :          0 :                 Py_DECREF(tag);
        3279                 :          0 :                 return;
        3280                 :            :             }
        3281                 :          0 :             attrib_in += 2;
        3282                 :            :         }
        3283                 :            :     } else {
        3284                 :          0 :         attrib = NULL;
        3285                 :            :     }
        3286                 :            :
        3287                 :          0 :     elementtreestate *st = self->state;
        3288         [ #  # ]:          0 :     if (TreeBuilder_CheckExact(st, self->target)) {
        3289                 :            :         /* shortcut */
        3290                 :          0 :         res = treebuilder_handle_start((TreeBuilderObject*) self->target,
        3291                 :            :                                        tag, attrib);
        3292                 :            :     }
        3293         [ #  # ]:          0 :     else if (self->handle_start) {
        3294         [ #  # ]:          0 :         if (attrib == NULL) {
        3295                 :          0 :             attrib = PyDict_New();
        3296         [ #  # ]:          0 :             if (!attrib) {
        3297                 :          0 :                 Py_DECREF(tag);
        3298                 :          0 :                 return;
        3299                 :            :             }
        3300                 :            :         }
        3301                 :          0 :         res = PyObject_CallFunctionObjArgs(self->handle_start,
        3302                 :            :                                            tag, attrib, NULL);
        3303                 :            :     } else
        3304                 :          0 :         res = NULL;
        3305                 :            :
        3306                 :          0 :     Py_DECREF(tag);
        3307                 :          0 :     Py_XDECREF(attrib);
        3308                 :            :
        3309                 :          0 :     Py_XDECREF(res);
        3310                 :            : }
        3311                 :            :
        3312                 :            : static void
        3313                 :          0 : expat_data_handler(XMLParserObject* self, const XML_Char* data_in,
        3314                 :            :                    int data_len)
        3315                 :            : {
        3316                 :            :     PyObject* data;
        3317                 :            :     PyObject* res;
        3318                 :            :
        3319         [ #  # ]:          0 :     if (PyErr_Occurred())
        3320                 :          0 :         return;
        3321                 :            :
        3322                 :          0 :     data = PyUnicode_DecodeUTF8(data_in, data_len, "strict");
        3323         [ #  # ]:          0 :     if (!data)
        3324                 :          0 :         return; /* parser will look for errors */
        3325                 :            :
        3326                 :          0 :     elementtreestate *st = self->state;
        3327         [ #  # ]:          0 :     if (TreeBuilder_CheckExact(st, self->target))
        3328                 :            :         /* shortcut */
        3329                 :          0 :         res = treebuilder_handle_data((TreeBuilderObject*) self->target, data);
        3330         [ #  # ]:          0 :     else if (self->handle_data)
        3331                 :          0 :         res = PyObject_CallOneArg(self->handle_data, data);
        3332                 :            :     else
        3333                 :          0 :         res = NULL;
        3334                 :            :
        3335                 :          0 :     Py_DECREF(data);
        3336                 :            :
        3337                 :          0 :     Py_XDECREF(res);
        3338                 :            : }
        3339                 :            :
        3340                 :            : static void
        3341                 :          0 : expat_end_handler(XMLParserObject* self, const XML_Char* tag_in)
        3342                 :            : {
        3343                 :            :     PyObject* tag;
        3344                 :          0 :     PyObject* res = NULL;
        3345                 :            :
        3346         [ #  # ]:          0 :     if (PyErr_Occurred())
        3347                 :          0 :         return;
        3348                 :            :
        3349                 :          0 :     elementtreestate *st = self->state;
        3350         [ #  # ]:          0 :     if (TreeBuilder_CheckExact(st, self->target))
        3351                 :            :         /* shortcut */
        3352                 :            :         /* the standard tree builder doesn't look at the end tag */
        3353                 :          0 :         res = treebuilder_handle_end(
        3354                 :          0 :             (TreeBuilderObject*) self->target, Py_None
        3355                 :            :             );
        3356         [ #  # ]:          0 :     else if (self->handle_end) {
        3357                 :          0 :         tag = makeuniversal(self, tag_in);
        3358         [ #  # ]:          0 :         if (tag) {
        3359                 :          0 :             res = PyObject_CallOneArg(self->handle_end, tag);
        3360                 :          0 :             Py_DECREF(tag);
        3361                 :            :         }
        3362                 :            :     }
        3363                 :            :
        3364                 :          0 :     Py_XDECREF(res);
        3365                 :            : }
        3366                 :            :
        3367                 :            : static void
        3368                 :          0 : expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix_in,
        3369                 :            :                        const XML_Char *uri_in)
        3370                 :            : {
        3371                 :          0 :     PyObject* res = NULL;
        3372                 :            :     PyObject* uri;
        3373                 :            :     PyObject* prefix;
        3374                 :            :     PyObject* stack[2];
        3375                 :            :
        3376         [ #  # ]:          0 :     if (PyErr_Occurred())
        3377                 :          0 :         return;
        3378                 :            :
        3379         [ #  # ]:          0 :     if (!uri_in)
        3380                 :          0 :         uri_in = "";
        3381         [ #  # ]:          0 :     if (!prefix_in)
        3382                 :          0 :         prefix_in = "";
        3383                 :            :
        3384                 :          0 :     elementtreestate *st = self->state;
        3385         [ #  # ]:          0 :     if (TreeBuilder_CheckExact(st, self->target)) {
        3386                 :            :         /* shortcut - TreeBuilder does not actually implement .start_ns() */
        3387                 :          0 :         TreeBuilderObject *target = (TreeBuilderObject*) self->target;
        3388                 :            :
        3389   [ #  #  #  # ]:          0 :         if (target->events_append && target->start_ns_event_obj) {
        3390                 :          0 :             prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict");
        3391         [ #  # ]:          0 :             if (!prefix)
        3392                 :          0 :                 return;
        3393                 :          0 :             uri = PyUnicode_DecodeUTF8(uri_in, strlen(uri_in), "strict");
        3394         [ #  # ]:          0 :             if (!uri) {
        3395                 :          0 :                 Py_DECREF(prefix);
        3396                 :          0 :                 return;
        3397                 :            :             }
        3398                 :            :
        3399                 :          0 :             res = treebuilder_handle_start_ns(target, prefix, uri);
        3400                 :          0 :             Py_DECREF(uri);
        3401                 :          0 :             Py_DECREF(prefix);
        3402                 :            :         }
        3403         [ #  # ]:          0 :     } else if (self->handle_start_ns) {
        3404                 :          0 :         prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict");
        3405         [ #  # ]:          0 :         if (!prefix)
        3406                 :          0 :             return;
        3407                 :          0 :         uri = PyUnicode_DecodeUTF8(uri_in, strlen(uri_in), "strict");
        3408         [ #  # ]:          0 :         if (!uri) {
        3409                 :          0 :             Py_DECREF(prefix);
        3410                 :          0 :             return;
        3411                 :            :         }
        3412                 :            :
        3413                 :          0 :         stack[0] = prefix;
        3414                 :          0 :         stack[1] = uri;
        3415                 :          0 :         res = _PyObject_FastCall(self->handle_start_ns, stack, 2);
        3416                 :          0 :         Py_DECREF(uri);
        3417                 :          0 :         Py_DECREF(prefix);
        3418                 :            :     }
        3419                 :            :
        3420                 :          0 :     Py_XDECREF(res);
        3421                 :            : }
        3422                 :            :
        3423                 :            : static void
        3424                 :          0 : expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in)
        3425                 :            : {
        3426                 :          0 :     PyObject *res = NULL;
        3427                 :            :     PyObject* prefix;
        3428                 :            :
        3429         [ #  # ]:          0 :     if (PyErr_Occurred())
        3430                 :          0 :         return;
        3431                 :            :
        3432         [ #  # ]:          0 :     if (!prefix_in)
        3433                 :          0 :         prefix_in = "";
        3434                 :            :
        3435                 :          0 :     elementtreestate *st = self->state;
        3436         [ #  # ]:          0 :     if (TreeBuilder_CheckExact(st, self->target)) {
        3437                 :            :         /* shortcut - TreeBuilder does not actually implement .end_ns() */
        3438                 :          0 :         TreeBuilderObject *target = (TreeBuilderObject*) self->target;
        3439                 :            :
        3440   [ #  #  #  # ]:          0 :         if (target->events_append && target->end_ns_event_obj) {
        3441                 :          0 :             res = treebuilder_handle_end_ns(target, Py_None);
        3442                 :            :         }
        3443         [ #  # ]:          0 :     } else if (self->handle_end_ns) {
        3444                 :          0 :         prefix = PyUnicode_DecodeUTF8(prefix_in, strlen(prefix_in), "strict");
        3445         [ #  # ]:          0 :         if (!prefix)
        3446                 :          0 :             return;
        3447                 :            :
        3448                 :          0 :         res = PyObject_CallOneArg(self->handle_end_ns, prefix);
        3449                 :          0 :         Py_DECREF(prefix);
        3450                 :            :     }
        3451                 :            :
        3452                 :          0 :     Py_XDECREF(res);
        3453                 :            : }
        3454                 :            :
        3455                 :            : static void
        3456                 :          0 : expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in)
        3457                 :            : {
        3458                 :            :     PyObject* comment;
        3459                 :            :     PyObject* res;
        3460                 :            :
        3461         [ #  # ]:          0 :     if (PyErr_Occurred())
        3462                 :          0 :         return;
        3463                 :            :
        3464                 :          0 :     elementtreestate *st = self->state;
        3465         [ #  # ]:          0 :     if (TreeBuilder_CheckExact(st, self->target)) {
        3466                 :            :         /* shortcut */
        3467                 :          0 :         TreeBuilderObject *target = (TreeBuilderObject*) self->target;
        3468                 :            :
        3469                 :          0 :         comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict");
        3470         [ #  # ]:          0 :         if (!comment)
        3471                 :          0 :             return; /* parser will look for errors */
        3472                 :            :
        3473                 :          0 :         res = treebuilder_handle_comment(target,  comment);
        3474                 :          0 :         Py_XDECREF(res);
        3475                 :          0 :         Py_DECREF(comment);
        3476         [ #  # ]:          0 :     } else if (self->handle_comment) {
        3477                 :          0 :         comment = PyUnicode_DecodeUTF8(comment_in, strlen(comment_in), "strict");
        3478         [ #  # ]:          0 :         if (!comment)
        3479                 :          0 :             return;
        3480                 :            :
        3481                 :          0 :         res = PyObject_CallOneArg(self->handle_comment, comment);
        3482                 :          0 :         Py_XDECREF(res);
        3483                 :          0 :         Py_DECREF(comment);
        3484                 :            :     }
        3485                 :            : }
        3486                 :            :
        3487                 :            : static void
        3488                 :          0 : expat_start_doctype_handler(XMLParserObject *self,
        3489                 :            :                             const XML_Char *doctype_name,
        3490                 :            :                             const XML_Char *sysid,
        3491                 :            :                             const XML_Char *pubid,
        3492                 :            :                             int has_internal_subset)
        3493                 :            : {
        3494                 :            :     PyObject *doctype_name_obj, *sysid_obj, *pubid_obj;
        3495                 :            :     PyObject *res;
        3496                 :            :
        3497         [ #  # ]:          0 :     if (PyErr_Occurred())
        3498                 :          0 :         return;
        3499                 :            :
        3500                 :          0 :     doctype_name_obj = makeuniversal(self, doctype_name);
        3501         [ #  # ]:          0 :     if (!doctype_name_obj)
        3502                 :          0 :         return;
        3503                 :            :
        3504         [ #  # ]:          0 :     if (sysid) {
        3505                 :          0 :         sysid_obj = makeuniversal(self, sysid);
        3506         [ #  # ]:          0 :         if (!sysid_obj) {
        3507                 :          0 :             Py_DECREF(doctype_name_obj);
        3508                 :          0 :             return;
        3509                 :            :         }
        3510                 :            :     } else {
        3511                 :          0 :         sysid_obj = Py_NewRef(Py_None);
        3512                 :            :     }
        3513                 :            :
        3514         [ #  # ]:          0 :     if (pubid) {
        3515                 :          0 :         pubid_obj = makeuniversal(self, pubid);
        3516         [ #  # ]:          0 :         if (!pubid_obj) {
        3517                 :          0 :             Py_DECREF(doctype_name_obj);
        3518                 :          0 :             Py_DECREF(sysid_obj);
        3519                 :          0 :             return;
        3520                 :            :         }
        3521                 :            :     } else {
        3522                 :          0 :         pubid_obj = Py_NewRef(Py_None);
        3523                 :            :     }
        3524                 :            :
        3525                 :          0 :     elementtreestate *st = self->state;
        3526                 :            :     /* If the target has a handler for doctype, call it. */
        3527         [ #  # ]:          0 :     if (self->handle_doctype) {
        3528                 :          0 :         res = PyObject_CallFunctionObjArgs(self->handle_doctype,
        3529                 :            :                                            doctype_name_obj, pubid_obj,
        3530                 :            :                                            sysid_obj, NULL);
        3531                 :          0 :         Py_XDECREF(res);
        3532                 :            :     }
        3533         [ #  # ]:          0 :     else if (_PyObject_LookupAttr((PyObject *)self, st->str_doctype, &res) > 0) {
        3534                 :          0 :         (void)PyErr_WarnEx(PyExc_RuntimeWarning,
        3535                 :            :                 "The doctype() method of XMLParser is ignored.  "
        3536                 :            :                 "Define doctype() method on the TreeBuilder target.",
        3537                 :            :                 1);
        3538                 :          0 :         Py_DECREF(res);
        3539                 :            :     }
        3540                 :            :
        3541                 :          0 :     Py_DECREF(doctype_name_obj);
        3542                 :          0 :     Py_DECREF(pubid_obj);
        3543                 :          0 :     Py_DECREF(sysid_obj);
        3544                 :            : }
        3545                 :            :
        3546                 :            : static void
        3547                 :          0 : expat_pi_handler(XMLParserObject* self, const XML_Char* target_in,
        3548                 :            :                  const XML_Char* data_in)
        3549                 :            : {
        3550                 :            :     PyObject* pi_target;
        3551                 :            :     PyObject* data;
        3552                 :            :     PyObject* res;
        3553                 :            :     PyObject* stack[2];
        3554                 :            :
        3555         [ #  # ]:          0 :     if (PyErr_Occurred())
        3556                 :          0 :         return;
        3557                 :            :
        3558                 :          0 :     elementtreestate *st = self->state;
        3559         [ #  # ]:          0 :     if (TreeBuilder_CheckExact(st, self->target)) {
        3560                 :            :         /* shortcut */
        3561                 :          0 :         TreeBuilderObject *target = (TreeBuilderObject*) self->target;
        3562                 :            :
        3563   [ #  #  #  #  :          0 :         if ((target->events_append && target->pi_event_obj) || target->insert_pis) {
                       #  # ]
        3564                 :          0 :             pi_target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict");
        3565         [ #  # ]:          0 :             if (!pi_target)
        3566                 :          0 :                 goto error;
        3567                 :          0 :             data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict");
        3568         [ #  # ]:          0 :             if (!data)
        3569                 :          0 :                 goto error;
        3570                 :          0 :             res = treebuilder_handle_pi(target, pi_target, data);
        3571                 :          0 :             Py_XDECREF(res);
        3572                 :          0 :             Py_DECREF(data);
        3573                 :          0 :             Py_DECREF(pi_target);
        3574                 :            :         }
        3575         [ #  # ]:          0 :     } else if (self->handle_pi) {
        3576                 :          0 :         pi_target = PyUnicode_DecodeUTF8(target_in, strlen(target_in), "strict");
        3577         [ #  # ]:          0 :         if (!pi_target)
        3578                 :          0 :             goto error;
        3579                 :          0 :         data = PyUnicode_DecodeUTF8(data_in, strlen(data_in), "strict");
        3580         [ #  # ]:          0 :         if (!data)
        3581                 :          0 :             goto error;
        3582                 :            :
        3583                 :          0 :         stack[0] = pi_target;
        3584                 :          0 :         stack[1] = data;
        3585                 :          0 :         res = _PyObject_FastCall(self->handle_pi, stack, 2);
        3586                 :          0 :         Py_XDECREF(res);
        3587                 :          0 :         Py_DECREF(data);
        3588                 :          0 :         Py_DECREF(pi_target);
        3589                 :            :     }
        3590                 :            :
        3591                 :          0 :     return;
        3592                 :            :
        3593                 :          0 :   error:
        3594                 :          0 :     Py_XDECREF(pi_target);
        3595                 :          0 :     return;
        3596                 :            : }
        3597                 :            :
        3598                 :            : /* -------------------------------------------------------------------- */
        3599                 :            :
        3600                 :            : static PyObject *
        3601                 :          0 : xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
        3602                 :            : {
        3603                 :          0 :     XMLParserObject *self = (XMLParserObject *)type->tp_alloc(type, 0);
        3604         [ #  # ]:          0 :     if (self) {
        3605                 :          0 :         self->parser = NULL;
        3606                 :          0 :         self->target = self->entity = self->names = NULL;
        3607                 :          0 :         self->handle_start_ns = self->handle_end_ns = NULL;
        3608                 :          0 :         self->handle_start = self->handle_data = self->handle_end = NULL;
        3609                 :          0 :         self->handle_comment = self->handle_pi = self->handle_close = NULL;
        3610                 :          0 :         self->handle_doctype = NULL;
        3611                 :          0 :         self->state = get_elementtree_state_by_type(type);
        3612                 :            :     }
        3613                 :          0 :     return (PyObject *)self;
        3614                 :            : }
        3615                 :            :
        3616                 :            : static int
        3617                 :          0 : ignore_attribute_error(PyObject *value)
        3618                 :            : {
        3619         [ #  # ]:          0 :     if (value == NULL) {
        3620         [ #  # ]:          0 :         if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
        3621                 :          0 :             return -1;
        3622                 :            :         }
        3623                 :          0 :         PyErr_Clear();
        3624                 :            :     }
        3625                 :          0 :     return 0;
        3626                 :            : }
        3627                 :            :
        3628                 :            : /*[clinic input]
        3629                 :            : _elementtree.XMLParser.__init__
        3630                 :            :
        3631                 :            :     *
        3632                 :            :     target: object = None
        3633                 :            :     encoding: str(accept={str, NoneType}) = None
        3634                 :            :
        3635                 :            : [clinic start generated code]*/
        3636                 :            :
        3637                 :            : static int
        3638                 :          0 : _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
        3639                 :            :                                      const char *encoding)
        3640                 :            : /*[clinic end generated code: output=3ae45ec6cdf344e4 input=7e716dd6e4f3e439]*/
        3641                 :            : {
        3642                 :          0 :     self->entity = PyDict_New();
        3643         [ #  # ]:          0 :     if (!self->entity)
        3644                 :          0 :         return -1;
        3645                 :            :
        3646                 :          0 :     self->names = PyDict_New();
        3647         [ #  # ]:          0 :     if (!self->names) {
        3648         [ #  # ]:          0 :         Py_CLEAR(self->entity);
        3649                 :          0 :         return -1;
        3650                 :            :     }
        3651                 :            :
        3652                 :          0 :     self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
        3653         [ #  # ]:          0 :     if (!self->parser) {
        3654         [ #  # ]:          0 :         Py_CLEAR(self->entity);
        3655         [ #  # ]:          0 :         Py_CLEAR(self->names);
        3656                 :          0 :         PyErr_NoMemory();
        3657                 :          0 :         return -1;
        3658                 :            :     }
        3659                 :            :     /* expat < 2.1.0 has no XML_SetHashSalt() */
        3660         [ #  # ]:          0 :     if (EXPAT(SetHashSalt) != NULL) {
        3661                 :          0 :         EXPAT(SetHashSalt)(self->parser,
        3662                 :          0 :                            (unsigned long)_Py_HashSecret.expat.hashsalt);
        3663                 :            :     }
        3664                 :            :
        3665         [ #  # ]:          0 :     if (target != Py_None) {
        3666                 :          0 :         Py_INCREF(target);
        3667                 :            :     } else {
        3668                 :          0 :         elementtreestate *st = self->state;
        3669                 :          0 :         target = treebuilder_new(st->TreeBuilder_Type, NULL, NULL);
        3670         [ #  # ]:          0 :         if (!target) {
        3671         [ #  # ]:          0 :             Py_CLEAR(self->entity);
        3672         [ #  # ]:          0 :             Py_CLEAR(self->names);
        3673                 :          0 :             return -1;
        3674                 :            :         }
        3675                 :            :     }
        3676                 :          0 :     self->target = target;
        3677                 :            :
        3678                 :          0 :     self->handle_start_ns = PyObject_GetAttrString(target, "start_ns");
        3679         [ #  # ]:          0 :     if (ignore_attribute_error(self->handle_start_ns)) {
        3680                 :          0 :         return -1;
        3681                 :            :     }
        3682                 :          0 :     self->handle_end_ns = PyObject_GetAttrString(target, "end_ns");
        3683         [ #  # ]:          0 :     if (ignore_attribute_error(self->handle_end_ns)) {
        3684                 :          0 :         return -1;
        3685                 :            :     }
        3686                 :          0 :     self->handle_start = PyObject_GetAttrString(target, "start");
        3687         [ #  # ]:          0 :     if (ignore_attribute_error(self->handle_start)) {
        3688                 :          0 :         return -1;
        3689                 :            :     }
        3690                 :          0 :     self->handle_data = PyObject_GetAttrString(target, "data");
        3691         [ #  # ]:          0 :     if (ignore_attribute_error(self->handle_data)) {
        3692                 :          0 :         return -1;
        3693                 :            :     }
        3694                 :          0 :     self->handle_end = PyObject_GetAttrString(target, "end");
        3695         [ #  # ]:          0 :     if (ignore_attribute_error(self->handle_end)) {
        3696                 :          0 :         return -1;
        3697                 :            :     }
        3698                 :          0 :     self->handle_comment = PyObject_GetAttrString(target, "comment");
        3699         [ #  # ]:          0 :     if (ignore_attribute_error(self->handle_comment)) {
        3700                 :          0 :         return -1;
        3701                 :            :     }
        3702                 :          0 :     self->handle_pi = PyObject_GetAttrString(target, "pi");
        3703         [ #  # ]:          0 :     if (ignore_attribute_error(self->handle_pi)) {
        3704                 :          0 :         return -1;
        3705                 :            :     }
        3706                 :          0 :     self->handle_close = PyObject_GetAttrString(target, "close");
        3707         [ #  # ]:          0 :     if (ignore_attribute_error(self->handle_close)) {
        3708                 :          0 :         return -1;
        3709                 :            :     }
        3710                 :          0 :     self->handle_doctype = PyObject_GetAttrString(target, "doctype");
        3711         [ #  # ]:          0 :     if (ignore_attribute_error(self->handle_doctype)) {
        3712                 :          0 :         return -1;
        3713                 :            :     }
        3714                 :            :
        3715                 :            :     /* configure parser */
        3716                 :          0 :     EXPAT(SetUserData)(self->parser, self);
        3717   [ #  #  #  # ]:          0 :     if (self->handle_start_ns || self->handle_end_ns)
        3718                 :          0 :         EXPAT(SetNamespaceDeclHandler)(
        3719                 :            :             self->parser,
        3720                 :            :             (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
        3721                 :            :             (XML_EndNamespaceDeclHandler) expat_end_ns_handler
        3722                 :            :             );
        3723                 :          0 :     EXPAT(SetElementHandler)(
        3724                 :            :         self->parser,
        3725                 :            :         (XML_StartElementHandler) expat_start_handler,
        3726                 :            :         (XML_EndElementHandler) expat_end_handler
        3727                 :            :         );
        3728                 :          0 :     EXPAT(SetDefaultHandlerExpand)(
        3729                 :            :         self->parser,
        3730                 :            :         (XML_DefaultHandler) expat_default_handler
        3731                 :            :         );
        3732                 :          0 :     EXPAT(SetCharacterDataHandler)(
        3733                 :            :         self->parser,
        3734                 :            :         (XML_CharacterDataHandler) expat_data_handler
        3735                 :            :         );
        3736         [ #  # ]:          0 :     if (self->handle_comment)
        3737                 :          0 :         EXPAT(SetCommentHandler)(
        3738                 :            :             self->parser,
        3739                 :            :             (XML_CommentHandler) expat_comment_handler
        3740                 :            :             );
        3741         [ #  # ]:          0 :     if (self->handle_pi)
        3742                 :          0 :         EXPAT(SetProcessingInstructionHandler)(
        3743                 :            :             self->parser,
        3744                 :            :             (XML_ProcessingInstructionHandler) expat_pi_handler
        3745                 :            :             );
        3746                 :          0 :     EXPAT(SetStartDoctypeDeclHandler)(
        3747                 :            :         self->parser,
        3748                 :            :         (XML_StartDoctypeDeclHandler) expat_start_doctype_handler
        3749                 :            :         );
        3750                 :          0 :     EXPAT(SetUnknownEncodingHandler)(
        3751                 :            :         self->parser,
        3752                 :          0 :         EXPAT(DefaultUnknownEncodingHandler), NULL
        3753                 :            :         );
        3754                 :            :
        3755                 :          0 :     return 0;
        3756                 :            : }
        3757                 :            :
        3758                 :            : static int
        3759                 :          0 : xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg)
        3760                 :            : {
        3761   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(self));
        3762   [ #  #  #  # ]:          0 :     Py_VISIT(self->handle_close);
        3763   [ #  #  #  # ]:          0 :     Py_VISIT(self->handle_pi);
        3764   [ #  #  #  # ]:          0 :     Py_VISIT(self->handle_comment);
        3765   [ #  #  #  # ]:          0 :     Py_VISIT(self->handle_end);
        3766   [ #  #  #  # ]:          0 :     Py_VISIT(self->handle_data);
        3767   [ #  #  #  # ]:          0 :     Py_VISIT(self->handle_start);
        3768   [ #  #  #  # ]:          0 :     Py_VISIT(self->handle_start_ns);
        3769   [ #  #  #  # ]:          0 :     Py_VISIT(self->handle_end_ns);
        3770   [ #  #  #  # ]:          0 :     Py_VISIT(self->handle_doctype);
        3771                 :            :
        3772   [ #  #  #  # ]:          0 :     Py_VISIT(self->target);
        3773   [ #  #  #  # ]:          0 :     Py_VISIT(self->entity);
        3774   [ #  #  #  # ]:          0 :     Py_VISIT(self->names);
        3775                 :            :
        3776                 :          0 :     return 0;
        3777                 :            : }
        3778                 :            :
        3779                 :            : static int
        3780                 :          0 : xmlparser_gc_clear(XMLParserObject *self)
        3781                 :            : {
        3782         [ #  # ]:          0 :     if (self->parser != NULL) {
        3783                 :          0 :         XML_Parser parser = self->parser;
        3784                 :          0 :         self->parser = NULL;
        3785                 :          0 :         EXPAT(ParserFree)(parser);
        3786                 :            :     }
        3787                 :            :
        3788         [ #  # ]:          0 :     Py_CLEAR(self->handle_close);
        3789         [ #  # ]:          0 :     Py_CLEAR(self->handle_pi);
        3790         [ #  # ]:          0 :     Py_CLEAR(self->handle_comment);
        3791         [ #  # ]:          0 :     Py_CLEAR(self->handle_end);
        3792         [ #  # ]:          0 :     Py_CLEAR(self->handle_data);
        3793         [ #  # ]:          0 :     Py_CLEAR(self->handle_start);
        3794         [ #  # ]:          0 :     Py_CLEAR(self->handle_start_ns);
        3795         [ #  # ]:          0 :     Py_CLEAR(self->handle_end_ns);
        3796         [ #  # ]:          0 :     Py_CLEAR(self->handle_doctype);
        3797                 :            :
        3798         [ #  # ]:          0 :     Py_CLEAR(self->target);
        3799         [ #  # ]:          0 :     Py_CLEAR(self->entity);
        3800         [ #  # ]:          0 :     Py_CLEAR(self->names);
        3801                 :            :
        3802                 :          0 :     return 0;
        3803                 :            : }
        3804                 :            :
        3805                 :            : static void
        3806                 :          0 : xmlparser_dealloc(XMLParserObject* self)
        3807                 :            : {
        3808                 :          0 :     PyTypeObject *tp = Py_TYPE(self);
        3809                 :          0 :     PyObject_GC_UnTrack(self);
        3810                 :          0 :     xmlparser_gc_clear(self);
        3811                 :          0 :     tp->tp_free(self);
        3812                 :          0 :     Py_DECREF(tp);
        3813                 :          0 : }
        3814                 :            :
        3815                 :            : Py_LOCAL_INLINE(int)
        3816                 :          0 : _check_xmlparser(XMLParserObject* self)
        3817                 :            : {
        3818         [ #  # ]:          0 :     if (self->target == NULL) {
        3819                 :          0 :         PyErr_SetString(PyExc_ValueError,
        3820                 :            :                         "XMLParser.__init__() wasn't called");
        3821                 :          0 :         return 0;
        3822                 :            :     }
        3823                 :          0 :     return 1;
        3824                 :            : }
        3825                 :            :
        3826                 :            : LOCAL(PyObject*)
        3827                 :          0 : expat_parse(elementtreestate *st, XMLParserObject *self, const char *data,
        3828                 :            :             int data_len, int final)
        3829                 :            : {
        3830                 :            :     int ok;
        3831                 :            :
        3832                 :            :     assert(!PyErr_Occurred());
        3833                 :          0 :     ok = EXPAT(Parse)(self->parser, data, data_len, final);
        3834                 :            :
        3835         [ #  # ]:          0 :     if (PyErr_Occurred())
        3836                 :          0 :         return NULL;
        3837                 :            :
        3838         [ #  # ]:          0 :     if (!ok) {
        3839                 :          0 :         expat_set_error(
        3840                 :            :             st,
        3841                 :          0 :             EXPAT(GetErrorCode)(self->parser),
        3842                 :          0 :             EXPAT(GetErrorLineNumber)(self->parser),
        3843                 :          0 :             EXPAT(GetErrorColumnNumber)(self->parser),
        3844                 :            :             NULL
        3845                 :            :             );
        3846                 :          0 :         return NULL;
        3847                 :            :     }
        3848                 :            :
        3849                 :          0 :     Py_RETURN_NONE;
        3850                 :            : }
        3851                 :            :
        3852                 :            : /*[clinic input]
        3853                 :            : _elementtree.XMLParser.close
        3854                 :            :
        3855                 :            : [clinic start generated code]*/
        3856                 :            :
        3857                 :            : static PyObject *
        3858                 :          0 : _elementtree_XMLParser_close_impl(XMLParserObject *self)
        3859                 :            : /*[clinic end generated code: output=d68d375dd23bc7fb input=ca7909ca78c3abfe]*/
        3860                 :            : {
        3861                 :            :     /* end feeding data to parser */
        3862                 :            :
        3863                 :            :     PyObject* res;
        3864                 :            :
        3865         [ #  # ]:          0 :     if (!_check_xmlparser(self)) {
        3866                 :          0 :         return NULL;
        3867                 :            :     }
        3868                 :          0 :     elementtreestate *st = self->state;
        3869                 :          0 :     res = expat_parse(st, self, "", 0, 1);
        3870         [ #  # ]:          0 :     if (!res)
        3871                 :          0 :         return NULL;
        3872                 :            :
        3873         [ #  # ]:          0 :     if (TreeBuilder_CheckExact(st, self->target)) {
        3874                 :          0 :         Py_DECREF(res);
        3875                 :          0 :         return treebuilder_done((TreeBuilderObject*) self->target);
        3876                 :            :     }
        3877         [ #  # ]:          0 :     else if (self->handle_close) {
        3878                 :          0 :         Py_DECREF(res);
        3879                 :          0 :         return PyObject_CallNoArgs(self->handle_close);
        3880                 :            :     }
        3881                 :            :     else {
        3882                 :          0 :         return res;
        3883                 :            :     }
        3884                 :            : }
        3885                 :            :
        3886                 :            : /*[clinic input]
        3887                 :            : _elementtree.XMLParser.feed
        3888                 :            :
        3889                 :            :     data: object
        3890                 :            :     /
        3891                 :            :
        3892                 :            : [clinic start generated code]*/
        3893                 :            :
        3894                 :            : static PyObject *
        3895                 :          0 : _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data)
        3896                 :            : /*[clinic end generated code: output=e42b6a78eec7446d input=fe231b6b8de3ce1f]*/
        3897                 :            : {
        3898                 :            :     /* feed data to parser */
        3899                 :            :
        3900         [ #  # ]:          0 :     if (!_check_xmlparser(self)) {
        3901                 :          0 :         return NULL;
        3902                 :            :     }
        3903                 :          0 :     elementtreestate *st = self->state;
        3904         [ #  # ]:          0 :     if (PyUnicode_Check(data)) {
        3905                 :            :         Py_ssize_t data_len;
        3906                 :          0 :         const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len);
        3907         [ #  # ]:          0 :         if (data_ptr == NULL)
        3908                 :          0 :             return NULL;
        3909         [ #  # ]:          0 :         if (data_len > INT_MAX) {
        3910                 :          0 :             PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
        3911                 :          0 :             return NULL;
        3912                 :            :         }
        3913                 :            :         /* Explicitly set UTF-8 encoding. Return code ignored. */
        3914                 :          0 :         (void)EXPAT(SetEncoding)(self->parser, "utf-8");
        3915                 :            :
        3916                 :          0 :         return expat_parse(st, self, data_ptr, (int)data_len, 0);
        3917                 :            :     }
        3918                 :            :     else {
        3919                 :            :         Py_buffer view;
        3920                 :            :         PyObject *res;
        3921         [ #  # ]:          0 :         if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0)
        3922                 :          0 :             return NULL;
        3923         [ #  # ]:          0 :         if (view.len > INT_MAX) {
        3924                 :          0 :             PyBuffer_Release(&view);
        3925                 :          0 :             PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
        3926                 :          0 :             return NULL;
        3927                 :            :         }
        3928                 :          0 :         res = expat_parse(st, self, view.buf, (int)view.len, 0);
        3929                 :          0 :         PyBuffer_Release(&view);
        3930                 :          0 :         return res;
        3931                 :            :     }
        3932                 :            : }
        3933                 :            :
        3934                 :            : /*[clinic input]
        3935                 :            : _elementtree.XMLParser._parse_whole
        3936                 :            :
        3937                 :            :     file: object
        3938                 :            :     /
        3939                 :            :
        3940                 :            : [clinic start generated code]*/
        3941                 :            :
        3942                 :            : static PyObject *
        3943                 :          0 : _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file)
        3944                 :            : /*[clinic end generated code: output=f797197bb818dda3 input=19ecc893b6f3e752]*/
        3945                 :            : {
        3946                 :            :     /* (internal) parse the whole input, until end of stream */
        3947                 :            :     PyObject* reader;
        3948                 :            :     PyObject* buffer;
        3949                 :            :     PyObject* temp;
        3950                 :            :     PyObject* res;
        3951                 :            :
        3952         [ #  # ]:          0 :     if (!_check_xmlparser(self)) {
        3953                 :          0 :         return NULL;
        3954                 :            :     }
        3955                 :          0 :     reader = PyObject_GetAttrString(file, "read");
        3956         [ #  # ]:          0 :     if (!reader)
        3957                 :          0 :         return NULL;
        3958                 :            :
        3959                 :            :     /* read from open file object */
        3960                 :          0 :     elementtreestate *st = self->state;
        3961                 :            :     for (;;) {
        3962                 :            :
        3963                 :          0 :         buffer = PyObject_CallFunction(reader, "i", 64*1024);
        3964                 :            :
        3965         [ #  # ]:          0 :         if (!buffer) {
        3966                 :            :             /* read failed (e.g. due to KeyboardInterrupt) */
        3967                 :          0 :             Py_DECREF(reader);
        3968                 :          0 :             return NULL;
        3969                 :            :         }
        3970                 :            :
        3971         [ #  # ]:          0 :         if (PyUnicode_CheckExact(buffer)) {
        3972                 :            :             /* A unicode object is encoded into bytes using UTF-8 */
        3973         [ #  # ]:          0 :             if (PyUnicode_GET_LENGTH(buffer) == 0) {
        3974                 :          0 :                 Py_DECREF(buffer);
        3975                 :          0 :                 break;
        3976                 :            :             }
        3977                 :          0 :             temp = PyUnicode_AsEncodedString(buffer, "utf-8", "surrogatepass");
        3978                 :          0 :             Py_DECREF(buffer);
        3979         [ #  # ]:          0 :             if (!temp) {
        3980                 :            :                 /* Propagate exception from PyUnicode_AsEncodedString */
        3981                 :          0 :                 Py_DECREF(reader);
        3982                 :          0 :                 return NULL;
        3983                 :            :             }
        3984                 :          0 :             buffer = temp;
        3985                 :            :         }
        3986   [ #  #  #  # ]:          0 :         else if (!PyBytes_CheckExact(buffer) || PyBytes_GET_SIZE(buffer) == 0) {
        3987                 :          0 :             Py_DECREF(buffer);
        3988                 :          0 :             break;
        3989                 :            :         }
        3990                 :            :
        3991         [ #  # ]:          0 :         if (PyBytes_GET_SIZE(buffer) > INT_MAX) {
        3992                 :          0 :             Py_DECREF(buffer);
        3993                 :          0 :             Py_DECREF(reader);
        3994                 :          0 :             PyErr_SetString(PyExc_OverflowError, "size does not fit in an int");
        3995                 :          0 :             return NULL;
        3996                 :            :         }
        3997                 :          0 :         res = expat_parse(
        3998                 :          0 :             st, self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer),
        3999                 :            :             0);
        4000                 :            :
        4001                 :          0 :         Py_DECREF(buffer);
        4002                 :            :
        4003         [ #  # ]:          0 :         if (!res) {
        4004                 :          0 :             Py_DECREF(reader);
        4005                 :          0 :             return NULL;
        4006                 :            :         }
        4007                 :          0 :         Py_DECREF(res);
        4008                 :            :
        4009                 :            :     }
        4010                 :            :
        4011                 :          0 :     Py_DECREF(reader);
        4012                 :            :
        4013                 :          0 :     res = expat_parse(st, self, "", 0, 1);
        4014                 :            :
        4015   [ #  #  #  # ]:          0 :     if (res && TreeBuilder_CheckExact(st, self->target)) {
        4016                 :          0 :         Py_DECREF(res);
        4017                 :          0 :         return treebuilder_done((TreeBuilderObject*) self->target);
        4018                 :            :     }
        4019                 :            :
        4020                 :          0 :     return res;
        4021                 :            : }
        4022                 :            :
        4023                 :            : /*[clinic input]
        4024                 :            : _elementtree.XMLParser._setevents
        4025                 :            :
        4026                 :            :     events_queue: object
        4027                 :            :     events_to_report: object = None
        4028                 :            :     /
        4029                 :            :
        4030                 :            : [clinic start generated code]*/
        4031                 :            :
        4032                 :            : static PyObject *
        4033                 :          0 : _elementtree_XMLParser__setevents_impl(XMLParserObject *self,
        4034                 :            :                                        PyObject *events_queue,
        4035                 :            :                                        PyObject *events_to_report)
        4036                 :            : /*[clinic end generated code: output=1440092922b13ed1 input=abf90830a1c3b0fc]*/
        4037                 :            : {
        4038                 :            :     /* activate element event reporting */
        4039                 :            :     Py_ssize_t i;
        4040                 :            :     TreeBuilderObject *target;
        4041                 :            :     PyObject *events_append, *events_seq;
        4042                 :            :
        4043         [ #  # ]:          0 :     if (!_check_xmlparser(self)) {
        4044                 :          0 :         return NULL;
        4045                 :            :     }
        4046                 :          0 :     elementtreestate *st = self->state;
        4047         [ #  # ]:          0 :     if (!TreeBuilder_CheckExact(st, self->target)) {
        4048                 :          0 :         PyErr_SetString(
        4049                 :            :             PyExc_TypeError,
        4050                 :            :             "event handling only supported for ElementTree.TreeBuilder "
        4051                 :            :             "targets"
        4052                 :            :             );
        4053                 :          0 :         return NULL;
        4054                 :            :     }
        4055                 :            :
        4056                 :          0 :     target = (TreeBuilderObject*) self->target;
        4057                 :            :
        4058                 :          0 :     events_append = PyObject_GetAttrString(events_queue, "append");
        4059         [ #  # ]:          0 :     if (events_append == NULL)
        4060                 :          0 :         return NULL;
        4061                 :          0 :     Py_XSETREF(target->events_append, events_append);
        4062                 :            :
        4063                 :            :     /* clear out existing events */
        4064         [ #  # ]:          0 :     Py_CLEAR(target->start_event_obj);
        4065         [ #  # ]:          0 :     Py_CLEAR(target->end_event_obj);
        4066         [ #  # ]:          0 :     Py_CLEAR(target->start_ns_event_obj);
        4067         [ #  # ]:          0 :     Py_CLEAR(target->end_ns_event_obj);
        4068         [ #  # ]:          0 :     Py_CLEAR(target->comment_event_obj);
        4069         [ #  # ]:          0 :     Py_CLEAR(target->pi_event_obj);
        4070                 :            :
        4071         [ #  # ]:          0 :     if (events_to_report == Py_None) {
        4072                 :            :         /* default is "end" only */
        4073                 :          0 :         target->end_event_obj = PyUnicode_FromString("end");
        4074                 :          0 :         Py_RETURN_NONE;
        4075                 :            :     }
        4076                 :            :
        4077         [ #  # ]:          0 :     if (!(events_seq = PySequence_Fast(events_to_report,
        4078                 :            :                                        "events must be a sequence"))) {
        4079                 :          0 :         return NULL;
        4080                 :            :     }
        4081                 :            :
        4082   [ #  #  #  # ]:          0 :     for (i = 0; i < PySequence_Fast_GET_SIZE(events_seq); ++i) {
        4083         [ #  # ]:          0 :         PyObject *event_name_obj = PySequence_Fast_GET_ITEM(events_seq, i);
        4084                 :          0 :         const char *event_name = NULL;
        4085         [ #  # ]:          0 :         if (PyUnicode_Check(event_name_obj)) {
        4086                 :          0 :             event_name = PyUnicode_AsUTF8(event_name_obj);
        4087         [ #  # ]:          0 :         } else if (PyBytes_Check(event_name_obj)) {
        4088                 :          0 :             event_name = PyBytes_AS_STRING(event_name_obj);
        4089                 :            :         }
        4090         [ #  # ]:          0 :         if (event_name == NULL) {
        4091                 :          0 :             Py_DECREF(events_seq);
        4092                 :          0 :             PyErr_Format(PyExc_ValueError, "invalid events sequence");
        4093                 :          0 :             return NULL;
        4094                 :            :         }
        4095                 :            :
        4096         [ #  # ]:          0 :         if (strcmp(event_name, "start") == 0) {
        4097                 :          0 :             Py_XSETREF(target->start_event_obj, Py_NewRef(event_name_obj));
        4098         [ #  # ]:          0 :         } else if (strcmp(event_name, "end") == 0) {
        4099                 :          0 :             Py_XSETREF(target->end_event_obj, Py_NewRef(event_name_obj));
        4100         [ #  # ]:          0 :         } else if (strcmp(event_name, "start-ns") == 0) {
        4101                 :          0 :             Py_XSETREF(target->start_ns_event_obj, Py_NewRef(event_name_obj));
        4102                 :          0 :             EXPAT(SetNamespaceDeclHandler)(
        4103                 :            :                 self->parser,
        4104                 :            :                 (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
        4105                 :            :                 (XML_EndNamespaceDeclHandler) expat_end_ns_handler
        4106                 :            :                 );
        4107         [ #  # ]:          0 :         } else if (strcmp(event_name, "end-ns") == 0) {
        4108                 :          0 :             Py_XSETREF(target->end_ns_event_obj, Py_NewRef(event_name_obj));
        4109                 :          0 :             EXPAT(SetNamespaceDeclHandler)(
        4110                 :            :                 self->parser,
        4111                 :            :                 (XML_StartNamespaceDeclHandler) expat_start_ns_handler,
        4112                 :            :                 (XML_EndNamespaceDeclHandler) expat_end_ns_handler
        4113                 :            :                 );
        4114         [ #  # ]:          0 :         } else if (strcmp(event_name, "comment") == 0) {
        4115                 :          0 :             Py_XSETREF(target->comment_event_obj, Py_NewRef(event_name_obj));
        4116                 :          0 :             EXPAT(SetCommentHandler)(
        4117                 :            :                 self->parser,
        4118                 :            :                 (XML_CommentHandler) expat_comment_handler
        4119                 :            :                 );
        4120         [ #  # ]:          0 :         } else if (strcmp(event_name, "pi") == 0) {
        4121                 :          0 :             Py_XSETREF(target->pi_event_obj, Py_NewRef(event_name_obj));
        4122                 :          0 :             EXPAT(SetProcessingInstructionHandler)(
        4123                 :            :                 self->parser,
        4124                 :            :                 (XML_ProcessingInstructionHandler) expat_pi_handler
        4125                 :            :                 );
        4126                 :            :         } else {
        4127                 :          0 :             Py_DECREF(events_seq);
        4128                 :          0 :             PyErr_Format(PyExc_ValueError, "unknown event '%s'", event_name);
        4129                 :          0 :             return NULL;
        4130                 :            :         }
        4131                 :            :     }
        4132                 :            :
        4133                 :          0 :     Py_DECREF(events_seq);
        4134                 :          0 :     Py_RETURN_NONE;
        4135                 :            : }
        4136                 :            :
        4137                 :            : static PyMemberDef xmlparser_members[] = {
        4138                 :            :     {"entity", T_OBJECT, offsetof(XMLParserObject, entity), READONLY, NULL},
        4139                 :            :     {"target", T_OBJECT, offsetof(XMLParserObject, target), READONLY, NULL},
        4140                 :            :     {NULL}
        4141                 :            : };
        4142                 :            :
        4143                 :            : static PyObject*
        4144                 :          0 : xmlparser_version_getter(XMLParserObject *self, void *closure)
        4145                 :            : {
        4146                 :          0 :     return PyUnicode_FromFormat(
        4147                 :            :         "Expat %d.%d.%d", XML_MAJOR_VERSION,
        4148                 :            :         XML_MINOR_VERSION, XML_MICRO_VERSION);
        4149                 :            : }
        4150                 :            :
        4151                 :            : static PyGetSetDef xmlparser_getsetlist[] = {
        4152                 :            :     {"version", (getter)xmlparser_version_getter, NULL, NULL},
        4153                 :            :     {NULL},
        4154                 :            : };
        4155                 :            :
        4156                 :            : #define clinic_state() (get_elementtree_state_by_type(Py_TYPE(self)))
        4157                 :            : #include "clinic/_elementtree.c.h"
        4158                 :            : #undef clinic_state
        4159                 :            :
        4160                 :            : static PyMethodDef element_methods[] = {
        4161                 :            :
        4162                 :            :     _ELEMENTTREE_ELEMENT_CLEAR_METHODDEF
        4163                 :            :
        4164                 :            :     _ELEMENTTREE_ELEMENT_GET_METHODDEF
        4165                 :            :     _ELEMENTTREE_ELEMENT_SET_METHODDEF
        4166                 :            :
        4167                 :            :     _ELEMENTTREE_ELEMENT_FIND_METHODDEF
        4168                 :            :     _ELEMENTTREE_ELEMENT_FINDTEXT_METHODDEF
        4169                 :            :     _ELEMENTTREE_ELEMENT_FINDALL_METHODDEF
        4170                 :            :
        4171                 :            :     _ELEMENTTREE_ELEMENT_APPEND_METHODDEF
        4172                 :            :     _ELEMENTTREE_ELEMENT_EXTEND_METHODDEF
        4173                 :            :     _ELEMENTTREE_ELEMENT_INSERT_METHODDEF
        4174                 :            :     _ELEMENTTREE_ELEMENT_REMOVE_METHODDEF
        4175                 :            :
        4176                 :            :     _ELEMENTTREE_ELEMENT_ITER_METHODDEF
        4177                 :            :     _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF
        4178                 :            :     _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF
        4179                 :            :
        4180                 :            :     _ELEMENTTREE_ELEMENT_ITEMS_METHODDEF
        4181                 :            :     _ELEMENTTREE_ELEMENT_KEYS_METHODDEF
        4182                 :            :
        4183                 :            :     _ELEMENTTREE_ELEMENT_MAKEELEMENT_METHODDEF
        4184                 :            :
        4185                 :            :     _ELEMENTTREE_ELEMENT___COPY___METHODDEF
        4186                 :            :     _ELEMENTTREE_ELEMENT___DEEPCOPY___METHODDEF
        4187                 :            :     _ELEMENTTREE_ELEMENT___SIZEOF___METHODDEF
        4188                 :            :     _ELEMENTTREE_ELEMENT___GETSTATE___METHODDEF
        4189                 :            :     _ELEMENTTREE_ELEMENT___SETSTATE___METHODDEF
        4190                 :            :
        4191                 :            :     {NULL, NULL}
        4192                 :            : };
        4193                 :            :
        4194                 :            : static struct PyMemberDef element_members[] = {
        4195                 :            :     {"__weaklistoffset__", T_PYSSIZET, offsetof(ElementObject, weakreflist), READONLY},
        4196                 :            :     {NULL},
        4197                 :            : };
        4198                 :            :
        4199                 :            : static PyGetSetDef element_getsetlist[] = {
        4200                 :            :     {"tag",
        4201                 :            :         (getter)element_tag_getter,
        4202                 :            :         (setter)element_tag_setter,
        4203                 :            :         "A string identifying what kind of data this element represents"},
        4204                 :            :     {"text",
        4205                 :            :         (getter)element_text_getter,
        4206                 :            :         (setter)element_text_setter,
        4207                 :            :         "A string of text directly after the start tag, or None"},
        4208                 :            :     {"tail",
        4209                 :            :         (getter)element_tail_getter,
        4210                 :            :         (setter)element_tail_setter,
        4211                 :            :         "A string of text directly after the end tag, or None"},
        4212                 :            :     {"attrib",
        4213                 :            :         (getter)element_attrib_getter,
        4214                 :            :         (setter)element_attrib_setter,
        4215                 :            :         "A dictionary containing the element's attributes"},
        4216                 :            :     {NULL},
        4217                 :            : };
        4218                 :            :
        4219                 :            : static PyType_Slot element_slots[] = {
        4220                 :            :     {Py_tp_dealloc, element_dealloc},
        4221                 :            :     {Py_tp_repr, element_repr},
        4222                 :            :     {Py_tp_getattro, PyObject_GenericGetAttr},
        4223                 :            :     {Py_tp_traverse, element_gc_traverse},
        4224                 :            :     {Py_tp_clear, element_gc_clear},
        4225                 :            :     {Py_tp_methods, element_methods},
        4226                 :            :     {Py_tp_members, element_members},
        4227                 :            :     {Py_tp_getset, element_getsetlist},
        4228                 :            :     {Py_tp_init, element_init},
        4229                 :            :     {Py_tp_alloc, PyType_GenericAlloc},
        4230                 :            :     {Py_tp_new, element_new},
        4231                 :            :     {Py_sq_length, element_length},
        4232                 :            :     {Py_sq_item, element_getitem},
        4233                 :            :     {Py_sq_ass_item, element_setitem},
        4234                 :            :     {Py_nb_bool, element_bool},
        4235                 :            :     {Py_mp_length, element_length},
        4236                 :            :     {Py_mp_subscript, element_subscr},
        4237                 :            :     {Py_mp_ass_subscript, element_ass_subscr},
        4238                 :            :     {0, NULL},
        4239                 :            : };
        4240                 :            :
        4241                 :            : static PyType_Spec element_spec = {
        4242                 :            :     .name = "xml.etree.ElementTree.Element",
        4243                 :            :     .basicsize = sizeof(ElementObject),
        4244                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
        4245                 :            :               Py_TPFLAGS_IMMUTABLETYPE),
        4246                 :            :     .slots = element_slots,
        4247                 :            : };
        4248                 :            :
        4249                 :            : static PyMethodDef treebuilder_methods[] = {
        4250                 :            :     _ELEMENTTREE_TREEBUILDER_DATA_METHODDEF
        4251                 :            :     _ELEMENTTREE_TREEBUILDER_START_METHODDEF
        4252                 :            :     _ELEMENTTREE_TREEBUILDER_END_METHODDEF
        4253                 :            :     _ELEMENTTREE_TREEBUILDER_COMMENT_METHODDEF
        4254                 :            :     _ELEMENTTREE_TREEBUILDER_PI_METHODDEF
        4255                 :            :     _ELEMENTTREE_TREEBUILDER_CLOSE_METHODDEF
        4256                 :            :     {NULL, NULL}
        4257                 :            : };
        4258                 :            :
        4259                 :            : static PyType_Slot treebuilder_slots[] = {
        4260                 :            :     {Py_tp_dealloc, treebuilder_dealloc},
        4261                 :            :     {Py_tp_traverse, treebuilder_gc_traverse},
        4262                 :            :     {Py_tp_clear, treebuilder_gc_clear},
        4263                 :            :     {Py_tp_methods, treebuilder_methods},
        4264                 :            :     {Py_tp_init, _elementtree_TreeBuilder___init__},
        4265                 :            :     {Py_tp_alloc, PyType_GenericAlloc},
        4266                 :            :     {Py_tp_new, treebuilder_new},
        4267                 :            :     {0, NULL},
        4268                 :            : };
        4269                 :            :
        4270                 :            : static PyType_Spec treebuilder_spec = {
        4271                 :            :     .name = "xml.etree.ElementTree.TreeBuilder",
        4272                 :            :     .basicsize = sizeof(TreeBuilderObject),
        4273                 :            :     .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE,
        4274                 :            :     .slots = treebuilder_slots,
        4275                 :            : };
        4276                 :            :
        4277                 :            : static PyMethodDef xmlparser_methods[] = {
        4278                 :            :     _ELEMENTTREE_XMLPARSER_FEED_METHODDEF
        4279                 :            :     _ELEMENTTREE_XMLPARSER_CLOSE_METHODDEF
        4280                 :            :     _ELEMENTTREE_XMLPARSER__PARSE_WHOLE_METHODDEF
        4281                 :            :     _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF
        4282                 :            :     {NULL, NULL}
        4283                 :            : };
        4284                 :            :
        4285                 :            : static PyType_Slot xmlparser_slots[] = {
        4286                 :            :     {Py_tp_dealloc, xmlparser_dealloc},
        4287                 :            :     {Py_tp_traverse, xmlparser_gc_traverse},
        4288                 :            :     {Py_tp_clear, xmlparser_gc_clear},
        4289                 :            :     {Py_tp_methods, xmlparser_methods},
        4290                 :            :     {Py_tp_members, xmlparser_members},
        4291                 :            :     {Py_tp_getset, xmlparser_getsetlist},
        4292                 :            :     {Py_tp_init, _elementtree_XMLParser___init__},
        4293                 :            :     {Py_tp_alloc, PyType_GenericAlloc},
        4294                 :            :     {Py_tp_new, xmlparser_new},
        4295                 :            :     {0, NULL},
        4296                 :            : };
        4297                 :            :
        4298                 :            : static PyType_Spec xmlparser_spec = {
        4299                 :            :     .name = "xml.etree.ElementTree.XMLParser",
        4300                 :            :     .basicsize = sizeof(XMLParserObject),
        4301                 :            :     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
        4302                 :            :               Py_TPFLAGS_IMMUTABLETYPE),
        4303                 :            :     .slots = xmlparser_slots,
        4304                 :            : };
        4305                 :            :
        4306                 :            : /* ==================================================================== */
        4307                 :            : /* python module interface */
        4308                 :            :
        4309                 :            : static PyMethodDef _functions[] = {
        4310                 :            :     {"SubElement", _PyCFunction_CAST(subelement), METH_VARARGS | METH_KEYWORDS},
        4311                 :            :     _ELEMENTTREE__SET_FACTORIES_METHODDEF
        4312                 :            :     {NULL, NULL}
        4313                 :            : };
        4314                 :            :
        4315                 :            : #define CREATE_TYPE(module, type, spec) \
        4316                 :            : do {                                                                     \
        4317                 :            :     if (type != NULL) {                                                  \
        4318                 :            :         break;                                                           \
        4319                 :            :     }                                                                    \
        4320                 :            :     type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \
        4321                 :            :     if (type == NULL) {                                                  \
        4322                 :            :         goto error;                                                      \
        4323                 :            :     }                                                                    \
        4324                 :            : } while (0)
        4325                 :            :
        4326                 :            : static int
        4327                 :          1 : module_exec(PyObject *m)
        4328                 :            : {
        4329                 :          1 :     elementtreestate *st = get_elementtree_state(m);
        4330                 :            :
        4331                 :            :     /* Initialize object types */
        4332   [ -  +  -  + ]:          1 :     CREATE_TYPE(m, st->ElementIter_Type, &elementiter_spec);
        4333   [ -  +  -  + ]:          1 :     CREATE_TYPE(m, st->TreeBuilder_Type, &treebuilder_spec);
        4334   [ -  +  -  + ]:          1 :     CREATE_TYPE(m, st->Element_Type, &element_spec);
        4335   [ -  +  -  + ]:          1 :     CREATE_TYPE(m, st->XMLParser_Type, &xmlparser_spec);
        4336                 :            :
        4337                 :          1 :     st->deepcopy_obj = _PyImport_GetModuleAttrString("copy", "deepcopy");
        4338         [ -  + ]:          1 :     if (st->deepcopy_obj == NULL) {
        4339                 :          0 :         goto error;
        4340                 :            :     }
        4341                 :            :
        4342                 :            :     assert(!PyErr_Occurred());
        4343         [ -  + ]:          1 :     if (!(st->elementpath_obj = PyImport_ImportModule("xml.etree.ElementPath")))
        4344                 :          0 :         goto error;
        4345                 :            :
        4346                 :            :     /* link against pyexpat */
        4347                 :          1 :     expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0);
        4348         [ +  - ]:          1 :     if (expat_capi) {
        4349                 :            :         /* check that it's usable */
        4350         [ +  - ]:          1 :         if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 ||
        4351         [ +  - ]:          1 :             (size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) ||
        4352         [ +  - ]:          1 :             expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION ||
        4353         [ +  - ]:          1 :             expat_capi->MINOR_VERSION != XML_MINOR_VERSION ||
        4354         [ -  + ]:          1 :             expat_capi->MICRO_VERSION != XML_MICRO_VERSION) {
        4355                 :          0 :             PyErr_SetString(PyExc_ImportError,
        4356                 :            :                             "pyexpat version is incompatible");
        4357                 :          0 :             goto error;
        4358                 :            :         }
        4359                 :            :     } else {
        4360                 :          0 :         goto error;
        4361                 :            :     }
        4362                 :            :
        4363                 :          1 :     st->str_append = PyUnicode_InternFromString("append");
        4364         [ -  + ]:          1 :     if (st->str_append == NULL) {
        4365                 :          0 :         goto error;
        4366                 :            :     }
        4367                 :          1 :     st->str_find = PyUnicode_InternFromString("find");
        4368         [ -  + ]:          1 :     if (st->str_find == NULL) {
        4369                 :          0 :         goto error;
        4370                 :            :     }
        4371                 :          1 :     st->str_findall = PyUnicode_InternFromString("findall");
        4372         [ -  + ]:          1 :     if (st->str_findall == NULL) {
        4373                 :          0 :         goto error;
        4374                 :            :     }
        4375                 :          1 :     st->str_findtext = PyUnicode_InternFromString("findtext");
        4376         [ -  + ]:          1 :     if (st->str_findtext == NULL) {
        4377                 :          0 :         goto error;
        4378                 :            :     }
        4379                 :          1 :     st->str_iterfind = PyUnicode_InternFromString("iterfind");
        4380         [ -  + ]:          1 :     if (st->str_iterfind == NULL) {
        4381                 :          0 :         goto error;
        4382                 :            :     }
        4383                 :          1 :     st->str_tail = PyUnicode_InternFromString("tail");
        4384         [ -  + ]:          1 :     if (st->str_tail == NULL) {
        4385                 :          0 :         goto error;
        4386                 :            :     }
        4387                 :          1 :     st->str_text = PyUnicode_InternFromString("text");
        4388         [ -  + ]:          1 :     if (st->str_text == NULL) {
        4389                 :          0 :         goto error;
        4390                 :            :     }
        4391                 :          1 :     st->str_doctype = PyUnicode_InternFromString("doctype");
        4392         [ -  + ]:          1 :     if (st->str_doctype == NULL) {
        4393                 :          0 :         goto error;
        4394                 :            :     }
        4395                 :          1 :     st->parseerror_obj = PyErr_NewException(
        4396                 :            :         "xml.etree.ElementTree.ParseError", PyExc_SyntaxError, NULL
        4397                 :            :         );
        4398         [ -  + ]:          1 :     if (PyModule_AddObjectRef(m, "ParseError", st->parseerror_obj) < 0) {
        4399                 :          0 :         goto error;
        4400                 :            :     }
        4401                 :            :
        4402                 :          1 :     PyTypeObject *types[] = {
        4403                 :          1 :         st->Element_Type,
        4404                 :          1 :         st->TreeBuilder_Type,
        4405                 :          1 :         st->XMLParser_Type
        4406                 :            :     };
        4407                 :            :
        4408         [ +  + ]:          4 :     for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) {
        4409         [ -  + ]:          3 :         if (PyModule_AddType(m, types[i]) < 0) {
        4410                 :          0 :             goto error;
        4411                 :            :         }
        4412                 :            :     }
        4413                 :            :
        4414                 :          1 :     return 0;
        4415                 :            :
        4416                 :          0 : error:
        4417                 :          0 :     return -1;
        4418                 :            : }
        4419                 :            :
        4420                 :            : static struct PyModuleDef_Slot elementtree_slots[] = {
        4421                 :            :     {Py_mod_exec, module_exec},
        4422                 :            :     {0, NULL},
        4423                 :            : };
        4424                 :            :
        4425                 :            : static struct PyModuleDef elementtreemodule = {
        4426                 :            :     .m_base = PyModuleDef_HEAD_INIT,
        4427                 :            :     .m_name = "_elementtree",
        4428                 :            :     .m_size = sizeof(elementtreestate),
        4429                 :            :     .m_methods = _functions,
        4430                 :            :     .m_slots = elementtree_slots,
        4431                 :            :     .m_traverse = elementtree_traverse,
        4432                 :            :     .m_clear = elementtree_clear,
        4433                 :            :     .m_free = elementtree_free,
        4434                 :            : };
        4435                 :            :
        4436                 :            : PyMODINIT_FUNC
        4437                 :          1 : PyInit__elementtree(void)
        4438                 :            : {
        4439                 :          1 :     return PyModuleDef_Init(&elementtreemodule);
        4440                 :            : }

Generated by: LCOV version 1.14