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