| Home | Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf-8 -*-
2
3 """
4 Tests for the ElementTree API
5
6 Only test cases that apply equally well to etree and ElementTree
7 belong here. Note that there is a second test module called test_io.py
8 for IO related test cases.
9 """
10
11 from __future__ import absolute_import
12
13 import copy
14 import io
15 import operator
16 import os
17 import re
18 import sys
19 import textwrap
20 import unittest
21 from contextlib import contextmanager
22 from functools import wraps, partial
23 from itertools import islice
24
25 from .common_imports import (
26 BytesIO, etree, HelperTestCase,
27 ElementTree, cElementTree, ET_VERSION, CET_VERSION,
28 filter_by_version, fileInTestDir, canonicalize, tmpfile,
29 _str, _bytes, unicode, next, IS_PYTHON2
30 )
31
32 if cElementTree is not None and (CET_VERSION <= (1,0,7) or sys.version_info[0] >= 3):
33 cElementTree = None
34
35 if ElementTree is not None:
36 print("Comparing with ElementTree %s" % getattr(ElementTree, "VERSION", "?"))
37
38 if cElementTree is not None:
39 print("Comparing with cElementTree %s" % getattr(cElementTree, "VERSION", "?"))
43 def wrap(method):
44 @wraps(method)
45 def testfunc(self, *args):
46 if self.etree is not etree and sys.version_info < version:
47 raise unittest.SkipTest("requires ET in Python %s" % '.'.join(map(str, version)))
48 return method(self, *args)
49 return testfunc
50 return wrap
51
54 etree = None
55 required_versions_ET = {}
56 required_versions_cET = {}
57
59 try:
60 XMLParser = self.etree.XMLParser
61 except AttributeError:
62 assert 'ElementTree' in self.etree.__name__
63 XMLParser = self.etree.TreeBuilder
64 return XMLParser(**kwargs)
65
66 try:
67 HelperTestCase.assertRegex
68 except AttributeError:
71
72 @et_needs_pyversion(3, 6)
74 # Test element tree interface.
75
76 def check_string(string):
77 len(string)
78 for char in string:
79 self.assertEqual(len(char), 1,
80 msg="expected one-character string, got %r" % char)
81 new_string = string + ""
82 new_string = string + " "
83 string[:0]
84
85 def check_mapping(mapping):
86 len(mapping)
87 keys = mapping.keys()
88 items = mapping.items()
89 for key in keys:
90 item = mapping[key]
91 mapping["key"] = "value"
92 self.assertEqual(mapping["key"], "value",
93 msg="expected value string, got %r" % mapping["key"])
94
95 def check_element(element):
96 self.assertTrue(self.etree.iselement(element), msg="not an element")
97 direlem = dir(element)
98 for attr in 'tag', 'attrib', 'text', 'tail':
99 self.assertTrue(hasattr(element, attr),
100 msg='no %s member' % attr)
101 self.assertIn(attr, direlem,
102 msg='no %s visible by dir' % attr)
103
104 check_string(element.tag)
105 check_mapping(element.attrib)
106 if element.text is not None:
107 check_string(element.text)
108 if element.tail is not None:
109 check_string(element.tail)
110 for elem in element:
111 check_element(elem)
112
113 element = self.etree.Element("tag")
114 check_element(element)
115 tree = self.etree.ElementTree(element)
116 check_element(tree.getroot())
117 element = self.etree.Element(u"t\xe4g", key="value")
118 tree = self.etree.ElementTree(element)
119 # lxml and ET Py2: slightly different repr()
120 #self.assertRegex(repr(element), r"^<Element 't\xe4g' at 0x.*>$")
121 element = self.etree.Element("tag", key="value")
122
123 # Make sure all standard element methods exist.
124
125 def check_method(method):
126 self.assertTrue(hasattr(method, '__call__'),
127 msg="%s not callable" % method)
128
129 check_method(element.append)
130 check_method(element.extend)
131 check_method(element.insert)
132 check_method(element.remove)
133 check_method(element.getchildren)
134 check_method(element.find)
135 check_method(element.iterfind)
136 check_method(element.findall)
137 check_method(element.findtext)
138 check_method(element.clear)
139 check_method(element.get)
140 check_method(element.set)
141 check_method(element.keys)
142 check_method(element.items)
143 check_method(element.iter)
144 check_method(element.itertext)
145 check_method(element.getiterator)
146
147 # These methods return an iterable. See bug 6472.
148
149 def check_iter(it):
150 check_method(it.next if IS_PYTHON2 else it.__next__)
151
152 check_iter(element.iterfind("tag"))
153 check_iter(element.iterfind("*"))
154 check_iter(tree.iterfind("tag"))
155 check_iter(tree.iterfind("*"))
156
157 # These aliases are provided:
158
159 # not an alias in lxml
160 #self.assertEqual(self.etree.XML, self.etree.fromstring)
161 self.assertEqual(self.etree.PI, self.etree.ProcessingInstruction)
162
164 for i in range(10):
165 e = self.etree.Element('foo')
166 self.assertEqual(e.tag, 'foo')
167 self.assertEqual(e.text, None)
168 self.assertEqual(e.tail, None)
169
171 Element = self.etree.Element
172
173 root = Element('root')
174 root.append(Element('one'))
175 root.append(Element('two'))
176 root.append(Element('three'))
177 self.assertEqual(3, len(root))
178 self.assertEqual('one', root[0].tag)
179 self.assertEqual('two', root[1].tag)
180 self.assertEqual('three', root[2].tag)
181 self.assertRaises(IndexError, operator.getitem, root, 3)
182
183 # test weird dictionary interaction leading to segfault previously
185 root = self.etree.Element('root')
186 self.assertEqual(root.tag, "root")
187 add = self.etree.ElementTree(file=BytesIO('<foo>Foo</foo>'))
188 self.assertEqual(add.getroot().tag, "foo")
189 self.assertEqual(add.getroot().text, "Foo")
190 root.append(self.etree.Element('baz'))
191 self.assertEqual(root.tag, "root")
192 self.assertEqual(root[0].tag, "baz")
193
195 Element = self.etree.Element
196 SubElement = self.etree.SubElement
197
198 root = Element('root')
199 SubElement(root, 'one')
200 SubElement(root, 'two')
201 SubElement(root, 'three')
202 self.assertEqual(3, len(root))
203 self.assertEqual('one', root[0].tag)
204 self.assertEqual('two', root[1].tag)
205 self.assertEqual('three', root[2].tag)
206
208 Element = self.etree.Element
209 SubElement = self.etree.SubElement
210
211 root1 = Element('root')
212 SubElement(root1, 'one')
213 self.assertTrue(root1[0] in root1)
214
215 root2 = Element('root')
216 SubElement(root2, 'two')
217 SubElement(root2, 'three')
218 self.assertTrue(root2[0] in root2)
219 self.assertTrue(root2[1] in root2)
220
221 self.assertFalse(root1[0] in root2)
222 self.assertFalse(root2[0] in root1)
223 self.assertFalse(None in root2)
224
226 ElementTree = self.etree.ElementTree
227
228 f = BytesIO('<doc>Test<one>One</one></doc>')
229 doc = ElementTree(file=f)
230 root = doc.getroot()
231 self.assertEqual(1, len(root))
232 self.assertEqual('one', root[0].tag)
233 self.assertRaises(IndexError, operator.getitem, root, 1)
234
236 ElementTree = self.etree.ElementTree
237
238 f = BytesIO('<doc><one>One</one><two>Two</two>hm<three>Three</three></doc>')
239 doc = ElementTree(file=f)
240 root = doc.getroot()
241 self.assertEqual(3, len(root))
242 self.assertEqual('one', root[0].tag)
243 self.assertEqual('two', root[1].tag)
244 self.assertEqual('three', root[2].tag)
245
247 ElementTree = self.etree.ElementTree
248
249 f = BytesIO('<doc>Test</doc>')
250 doc = ElementTree(file=f)
251 root = doc.getroot()
252 self.assertEqual(0, len(root))
253
255 Element = self.etree.Element
256 SubElement = self.etree.SubElement
257 a = Element('a')
258 b = SubElement(a, 'b')
259 c = SubElement(a, 'c')
260 d = SubElement(a, 'd')
261 self.assertEqual(d, a[-1])
262 self.assertEqual(c, a[-2])
263 self.assertEqual(b, a[-3])
264 self.assertRaises(IndexError, operator.getitem, a, -4)
265 a[-1] = e = Element('e')
266 self.assertEqual(e, a[-1])
267 del a[-1]
268 self.assertEqual(2, len(a))
269
271 ElementTree = self.etree.ElementTree
272
273 f = BytesIO('<doc><one>One</one><two>Two</two></doc>')
274 doc = ElementTree(file=f)
275 root = doc.getroot()
276 self.assertEqual(2, len(root))
277 self.assertEqual('one', root[0].tag)
278 self.assertEqual('two', root[1].tag)
279
281 ElementTree = self.etree.ElementTree
282
283 f = BytesIO('<doc>This is a text</doc>')
284 doc = ElementTree(file=f)
285 root = doc.getroot()
286 self.assertEqual('This is a text', root.text)
287
289 ElementTree = self.etree.ElementTree
290
291 f = BytesIO('<doc></doc>')
292 doc = ElementTree(file=f)
293 root = doc.getroot()
294 self.assertEqual(None, root.text)
295
297 ElementTree = self.etree.ElementTree
298
299 f = BytesIO('<doc><one>One</one></doc>')
300 doc = ElementTree(file=f)
301 root = doc.getroot()
302 self.assertEqual(None, root.text)
303 self.assertEqual('One', root[0].text)
304
306 ElementTree = self.etree.ElementTree
307
308 f = BytesIO('<doc>This is > than a text</doc>')
309 doc = ElementTree(file=f)
310 root = doc.getroot()
311 self.assertEqual('This is > than a text', root.text)
312
314 Element = self.etree.Element
315
316 a = Element("a")
317 a.text = "<>&"
318 self.assertXML(_bytes('<a><>&</a>'),
319 a)
320
322 tostring = self.etree.tostring
323 Element = self.etree.Element
324
325 a = Element("a")
326 a.text = "<>&"
327 self.assertEqual(_bytes('<a><>&</a>'),
328 tostring(a))
329
335
336 a = Element("a")
337 a.text = strTest("text")
338 self.assertXML(_bytes('<a>text</a>'),
339 a)
340
342 ElementTree = self.etree.ElementTree
343
344 f = BytesIO('<doc>This is <i>mixed</i> content.</doc>')
345 doc = ElementTree(file=f)
346 root = doc.getroot()
347 self.assertEqual(1, len(root))
348 self.assertEqual('This is ', root.text)
349 self.assertEqual(None, root.tail)
350 self.assertEqual('mixed', root[0].text)
351 self.assertEqual(' content.', root[0].tail)
352
354 Element = self.etree.Element
355 SubElement = self.etree.SubElement
356
357 class strTest(str):
358 pass
359
360 a = Element("a")
361 SubElement(a, "t").tail = strTest("tail")
362 self.assertXML(_bytes('<a><t></t>tail</a>'),
363 a)
364
366 # this is discouraged for ET compat, should not be tested...
367 XML = self.etree.XML
368
369 root = XML(_bytes('<doc>This is <i>mixed</i> content.</doc>'))
370 self.assertEqual(1, len(root))
371 self.assertEqual('This is ', root.text)
372 self.assertEqual(None, root.tail)
373 self.assertEqual('mixed', root[0].text)
374 self.assertEqual(' content.', root[0].tail)
375
376 del root[0].tail
377
378 self.assertEqual(1, len(root))
379 self.assertEqual('This is ', root.text)
380 self.assertEqual(None, root.tail)
381 self.assertEqual('mixed', root[0].text)
382 self.assertEqual(None, root[0].tail)
383
384 root[0].tail = "TAIL"
385
386 self.assertEqual(1, len(root))
387 self.assertEqual('This is ', root.text)
388 self.assertEqual(None, root.tail)
389 self.assertEqual('mixed', root[0].text)
390 self.assertEqual('TAIL', root[0].tail)
391
393 Element = self.etree.Element
394 ElementTree = self.etree.ElementTree
395
396 el = Element('hoi')
397 doc = ElementTree(el)
398 root = doc.getroot()
399 self.assertEqual(None, root.text)
400 self.assertEqual('hoi', root.tag)
401
403 ElementTree = self.etree.ElementTree
404
405 f = BytesIO('<doc one="One" two="Two"/>')
406 doc = ElementTree(file=f)
407 root = doc.getroot()
408 self.assertEqual('One', root.attrib['one'])
409 self.assertEqual('Two', root.attrib['two'])
410 self.assertRaises(KeyError, operator.getitem, root.attrib, 'three')
411
413 ElementTree = self.etree.ElementTree
414
415 f = BytesIO('<doc one="One" two="Two"/>')
416 doc = ElementTree(file=f)
417 root = doc.getroot()
418 self.assertEqual('One', root.attrib.get('one'))
419 self.assertEqual('Two', root.attrib.get('two'))
420 self.assertEqual(None, root.attrib.get('three'))
421 self.assertEqual('foo', root.attrib.get('three', 'foo'))
422
424 ElementTree = self.etree.ElementTree
425
426 f = BytesIO('<doc one="One" two="Two"/>')
427 doc = ElementTree(file=f)
428 root = doc.getroot()
429 attrib = dict(root.attrib)
430 self.assertEqual('One', attrib['one'])
431 self.assertEqual('Two', attrib['two'])
432 self.assertRaises(KeyError, operator.getitem, attrib, 'three')
433
435 ElementTree = self.etree.ElementTree
436
437 f = BytesIO('<doc one="One" two="Two"/>')
438 doc = ElementTree(file=f)
439 root = doc.getroot()
440 attrib = copy.copy(root.attrib)
441 self.assertEqual('One', attrib['one'])
442 self.assertEqual('Two', attrib['two'])
443 self.assertRaises(KeyError, operator.getitem, attrib, 'three')
444
446 ElementTree = self.etree.ElementTree
447
448 f = BytesIO('<doc one="One" two="Two"/>')
449 doc = ElementTree(file=f)
450 root = doc.getroot()
451 attrib = copy.deepcopy(root.attrib)
452 self.assertEqual('One', attrib['one'])
453 self.assertEqual('Two', attrib['two'])
454 self.assertRaises(KeyError, operator.getitem, attrib, 'three')
455
457 ElementTree = self.etree.ElementTree
458
459 f = BytesIO('<doc one="One" two="Two"/>')
460 doc = ElementTree(file=f)
461 root = doc.getroot()
462 self.assertEqual('One', root.get('one'))
463 self.assertEqual('Two', root.get('two'))
464 self.assertEqual(None, root.get('three'))
465 self.assertEqual('foo', root.get('three', 'foo'))
466
468 XML = self.etree.XML
469
470 root = XML(_bytes('<doc one="One" two="Two"/>'))
471 self.assertEqual('One', root.get('one'))
472 self.assertEqual('Two', root.get('two'))
473 root.attrib.clear()
474 self.assertEqual(None, root.get('one'))
475 self.assertEqual(None, root.get('two'))
476
478 Element = self.etree.Element
479
480 root = Element("root", one="One")
481 root.set("two", "Two")
482 self.assertEqual('One', root.get('one'))
483 self.assertEqual('Two', root.get('two'))
484 root.attrib.clear()
485 self.assertEqual(None, root.get('one'))
486 self.assertEqual(None, root.get('two'))
487
489 Element = self.etree.Element
490 SubElement = self.etree.SubElement
491
492 attribNS = '{http://foo/bar}x'
493
494 parent = Element('parent')
495 parent.set(attribNS, 'a')
496 child = SubElement(parent, 'child')
497 child.set(attribNS, 'b')
498
499 self.assertEqual('a', parent.get(attribNS))
500 self.assertEqual('b', child.get(attribNS))
501
502 parent.clear()
503 self.assertEqual(None, parent.get(attribNS))
504 self.assertEqual('b', child.get(attribNS))
505
507 ElementTree = self.etree.ElementTree
508
509 f = BytesIO('<doc one="One" two="Two"/>')
510 doc = ElementTree(file=f)
511 root = doc.getroot()
512 self.assertEqual('One', root.attrib['one'])
513 self.assertEqual('Two', root.attrib['two'])
514
515 self.assertEqual('One', root.attrib.pop('one'))
516
517 self.assertEqual(None, root.attrib.get('one'))
518 self.assertEqual('Two', root.attrib['two'])
519
521 root = self.etree.XML(_bytes('<doc one="One" two="Two"/>'))
522 self.assertRaises(KeyError, root.attrib.pop, 'NONE')
523
524 self.assertEqual('One', root.attrib['one'])
525 self.assertEqual('Two', root.attrib['two'])
526
528 root = self.etree.XML(_bytes('<doc one="One" two="Two"/>'))
529 self.assertEqual('Three', root.attrib.pop('three', 'Three'))
530
532 root = self.etree.XML(_bytes('<doc/>'))
533 self.assertEqual('Three', root.attrib.pop('three', 'Three'))
534
536 root = self.etree.XML(_bytes('<doc one="One" two="Two"/>'))
537 self.assertRaises(TypeError, root.attrib.pop, 'One', None, None)
538
540 XML = self.etree.XML
541
542 root = XML(_bytes('<doc alpha="Alpha" beta="Beta"/>'))
543 items = list(root.attrib.items())
544 items.sort()
545 self.assertEqual(
546 [('alpha', 'Alpha'), ('beta', 'Beta')],
547 items)
548
549 root.attrib.update({'alpha' : 'test', 'gamma' : 'Gamma'})
550
551 items = list(root.attrib.items())
552 items.sort()
553 self.assertEqual(
554 [('alpha', 'test'), ('beta', 'Beta'), ('gamma', 'Gamma')],
555 items)
556
558 XML = self.etree.XML
559
560 root = XML(_bytes('<doc alpha="Alpha" beta="Beta"/>'))
561 items = list(root.attrib.items())
562 items.sort()
563 self.assertEqual(
564 [('alpha', 'Alpha'), ('beta', 'Beta')],
565 items)
566
567 root.attrib.update({'alpha' : 'test', 'gamma' : 'Gamma'}.items())
568
569 items = list(root.attrib.items())
570 items.sort()
571 self.assertEqual(
572 [('alpha', 'test'), ('beta', 'Beta'), ('gamma', 'Gamma')],
573 items)
574
576 XML = self.etree.XML
577
578 root = XML(_bytes('<doc alpha="Alpha" beta="Beta"/>'))
579 items = list(root.attrib.items())
580 items.sort()
581 self.assertEqual(
582 [('alpha', 'Alpha'), ('beta', 'Beta')],
583 items)
584
585 root.attrib.update(iter({'alpha' : 'test', 'gamma' : 'Gamma'}.items()))
586
587 items = list(root.attrib.items())
588 items.sort()
589 self.assertEqual(
590 [('alpha', 'test'), ('beta', 'Beta'), ('gamma', 'Gamma')],
591 items)
592
594 XML = self.etree.XML
595
596 root = XML(_bytes('<doc alpha="Alpha" beta="Beta"/>'))
597 items = list(root.attrib.items())
598 items.sort()
599 self.assertEqual(
600 [('alpha', 'Alpha'), ('beta', 'Beta')],
601 items)
602
603 other = XML(_bytes('<doc alpha="test" gamma="Gamma"/>'))
604 root.attrib.update(other.attrib)
605
606 items = list(root.attrib.items())
607 items.sort()
608 self.assertEqual(
609 [('alpha', 'test'), ('beta', 'Beta'), ('gamma', 'Gamma')],
610 items)
611
613 XML = self.etree.XML
614
615 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
616 keys = list(root.attrib.keys())
617 keys.sort()
618 self.assertEqual(['alpha', 'beta', 'gamma'], keys)
619
621 XML = self.etree.XML
622
623 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
624 keys = list(root.keys())
625 keys.sort()
626 self.assertEqual(['alpha', 'beta', 'gamma'], keys)
627
629 XML = self.etree.XML
630
631 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
632 items = list(root.items())
633 items.sort()
634 self.assertEqual(
635 [('alpha','Alpha'), ('beta','Beta'), ('gamma','Gamma')],
636 items)
637
639 XML = self.etree.XML
640
641 root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
642 keys = list(root.keys())
643 keys.sort()
644 self.assertEqual(['bar', '{http://ns.codespeak.net/test}baz'],
645 keys)
646
648 XML = self.etree.XML
649
650 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
651 values = list(root.attrib.values())
652 values.sort()
653 self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
654
656 XML = self.etree.XML
657
658 root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
659 values = list(root.attrib.values())
660 values.sort()
661 self.assertEqual(
662 ['Bar', 'Baz'], values)
663
665 XML = self.etree.XML
666
667 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
668 items = list(root.attrib.items())
669 items.sort()
670 self.assertEqual([
671 ('alpha', 'Alpha'),
672 ('beta', 'Beta'),
673 ('gamma', 'Gamma'),
674 ],
675 items)
676
678 XML = self.etree.XML
679
680 root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
681 items = list(root.attrib.items())
682 items.sort()
683 self.assertEqual(
684 [('bar', 'Bar'), ('{http://ns.codespeak.net/test}baz', 'Baz')],
685 items)
686
688 XML = self.etree.XML
689
690 expected = "{'{http://ns.codespeak.net/test}baz': 'Baz', 'bar': 'Bar'}"
691 alternative = "{'bar': 'Bar', '{http://ns.codespeak.net/test}baz': 'Baz'}"
692
693 root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
694 try:
695 self.assertEqual(expected, str(root.attrib))
696 except AssertionError:
697 self.assertEqual(alternative, str(root.attrib))
698
700 XML = self.etree.XML
701
702 root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
703 self.assertEqual(
704 True, 'bar' in root.attrib)
705 self.assertEqual(
706 False, 'baz' in root.attrib)
707 self.assertEqual(
708 False, 'hah' in root.attrib)
709 self.assertEqual(
710 True,
711 '{http://ns.codespeak.net/test}baz' in root.attrib)
712
714 Element = self.etree.Element
715
716 root = Element("root")
717 root.set("attr", "TEST")
718 self.assertEqual("TEST", root.get("attr"))
719
721 Element = self.etree.Element
722
723 root = Element("root")
724 root.set("attr", "TEST")
725 self.assertEqual("TEST", root.attrib["attr"])
726
727 root2 = Element("root2", root.attrib)
728 self.assertEqual("TEST", root2.attrib["attr"])
729
731 XML = self.etree.XML
732
733 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma" />'))
734 result = []
735 for key in root.attrib:
736 result.append(key)
737 result.sort()
738 self.assertEqual(['alpha', 'beta', 'gamma'], result)
739
741 Element = self.etree.Element
742
743 a = Element('a')
744 a.attrib['foo'] = 'Foo'
745 a.attrib['bar'] = 'Bar'
746 self.assertEqual('Foo', a.attrib['foo'])
747 del a.attrib['foo']
748 self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
749
751 Element = self.etree.Element
752
753 a = Element('a')
754 a.attrib['{http://a/}foo'] = 'Foo'
755 a.attrib['{http://a/}bar'] = 'Bar'
756 self.assertEqual(None, a.get('foo'))
757 self.assertEqual('Foo', a.get('{http://a/}foo'))
758 self.assertEqual('Foo', a.attrib['{http://a/}foo'])
759
760 self.assertRaises(KeyError, operator.delitem, a.attrib, 'foo')
761 self.assertEqual('Foo', a.attrib['{http://a/}foo'])
762
763 del a.attrib['{http://a/}foo']
764 self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
765
767 XML = self.etree.XML
768
769 a = XML(_bytes('<a xmlns:nsa="http://a/" nsa:foo="FooNS" foo="Foo" />'))
770
771 self.assertEqual('Foo', a.attrib['foo'])
772 self.assertEqual('FooNS', a.attrib['{http://a/}foo'])
773
774 del a.attrib['foo']
775 self.assertEqual('FooNS', a.attrib['{http://a/}foo'])
776 self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
777 self.assertRaises(KeyError, operator.delitem, a.attrib, 'foo')
778
779 del a.attrib['{http://a/}foo']
780 self.assertRaises(KeyError, operator.getitem, a.attrib, '{http://a/}foo')
781 self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
782
783 a = XML(_bytes('<a xmlns:nsa="http://a/" foo="Foo" nsa:foo="FooNS" />'))
784
785 self.assertEqual('Foo', a.attrib['foo'])
786 self.assertEqual('FooNS', a.attrib['{http://a/}foo'])
787
788 del a.attrib['foo']
789 self.assertEqual('FooNS', a.attrib['{http://a/}foo'])
790 self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
791
792 del a.attrib['{http://a/}foo']
793 self.assertRaises(KeyError, operator.getitem, a.attrib, '{http://a/}foo')
794 self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
795
797 XML = self.etree.XML
798
799 root = XML(_bytes('<doc>This is a text.</doc>'))
800 self.assertEqual(0, len(root))
801 self.assertEqual('This is a text.', root.text)
802
804 XMLID = self.etree.XMLID
805 XML = self.etree.XML
806 xml_text = _bytes('''
807 <document>
808 <h1 id="chapter1">...</h1>
809 <p id="note1" class="note">...</p>
810 <p>Regular paragraph.</p>
811 <p xml:id="xmlid">XML:ID paragraph.</p>
812 <p id="warn1" class="warning">...</p>
813 </document>
814 ''')
815
816 root, dic = XMLID(xml_text)
817 root2 = XML(xml_text)
818 self.assertEqual(self._writeElement(root),
819 self._writeElement(root2))
820 expected = {
821 "chapter1" : root[0],
822 "note1" : root[1],
823 "warn1" : root[4]
824 }
825 self.assertEqual(dic, expected)
826
828 fromstring = self.etree.fromstring
829
830 root = fromstring('<doc>This is a text.</doc>')
831 self.assertEqual(0, len(root))
832 self.assertEqual('This is a text.', root.text)
833
834 required_versions_ET['test_fromstringlist'] = (1,3)
836 fromstringlist = self.etree.fromstringlist
837
838 root = fromstringlist(["<do", "c>T", "hi", "s is",
839 " a text.<", "/doc", ">"])
840 self.assertEqual(0, len(root))
841 self.assertEqual('This is a text.', root.text)
842
843 required_versions_ET['test_fromstringlist_characters'] = (1,3)
845 fromstringlist = self.etree.fromstringlist
846
847 root = fromstringlist(list('<doc>This is a text.</doc>'))
848 self.assertEqual(0, len(root))
849 self.assertEqual('This is a text.', root.text)
850
851 required_versions_ET['test_fromstringlist_single'] = (1,3)
853 fromstringlist = self.etree.fromstringlist
854
855 root = fromstringlist(['<doc>This is a text.</doc>'])
856 self.assertEqual(0, len(root))
857 self.assertEqual('This is a text.', root.text)
858
860 iselement = self.etree.iselement
861 Element = self.etree.Element
862 ElementTree = self.etree.ElementTree
863 XML = self.etree.XML
864 Comment = self.etree.Comment
865 ProcessingInstruction = self.etree.ProcessingInstruction
866
867 el = Element('hoi')
868 self.assertTrue(iselement(el))
869
870 el2 = XML(_bytes('<foo/>'))
871 self.assertTrue(iselement(el2))
872
873 tree = ElementTree(element=Element('dag'))
874 self.assertTrue(not iselement(tree))
875 self.assertTrue(iselement(tree.getroot()))
876
877 c = Comment('test')
878 self.assertTrue(iselement(c))
879
880 p = ProcessingInstruction("test", "some text")
881 self.assertTrue(iselement(p))
882
884 XML = self.etree.XML
885
886 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
887 result = []
888 for el in root:
889 result.append(el.tag)
890 self.assertEqual(['one', 'two', 'three'], result)
891
893 XML = self.etree.XML
894
895 root = XML(_bytes('<doc></doc>'))
896 result = []
897 for el in root:
898 result.append(el.tag)
899 self.assertEqual([], result)
900
902 XML = self.etree.XML
903
904 root = XML(_bytes('<doc>Text</doc>'))
905 result = []
906 for el in root:
907 result.append(el.tag)
908 self.assertEqual([], result)
909
911 # this would cause a crash in the past
912 fromstring = self.etree.fromstring
913 root = fromstring('<html><p></p>x</html>')
914 for elem in root:
915 elem.tail = ''
916
918 # this would cause a crash in the past
919 fromstring = self.etree.fromstring
920 root = fromstring('<html><p></p>x</html>')
921 for elem in root:
922 elem.tail = None
923
925 XML = self.etree.XML
926 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
927 result = []
928 for el in reversed(root):
929 result.append(el.tag)
930 self.assertEqual(['three', 'two', 'one'], result)
931
933 XML = self.etree.XML
934
935 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
936 result = []
937 add = True
938 for el in root:
939 result.append(el.tag)
940 if add:
941 self.etree.SubElement(root, 'four')
942 add = False
943 self.assertEqual(['one', 'two', 'three', 'four'], result)
944
946 XML = self.etree.XML
947
948 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
949 result = []
950 for el in root:
951 result.append(el.tag)
952 del root[-1]
953 self.assertEqual(['one', 'two'], result)
954
956 XML = self.etree.XML
957
958 root = XML(_bytes('<doc><one/><two/></doc>'))
959 result = []
960 for el0 in root:
961 result.append(el0.tag)
962 for el1 in root:
963 result.append(el1.tag)
964 self.assertEqual(['one','one', 'two', 'two', 'one', 'two'], result)
965
966 required_versions_ET['test_itertext'] = (1,3)
968 # ET 1.3+
969 XML = self.etree.XML
970 root = XML(_bytes("<root>RTEXT<a></a>ATAIL<b/><c>CTEXT</c>CTAIL</root>"))
971
972 text = list(root.itertext())
973 self.assertEqual(["RTEXT", "ATAIL", "CTEXT", "CTAIL"],
974 text)
975
976 required_versions_ET['test_itertext_child'] = (1,3)
978 # ET 1.3+
979 XML = self.etree.XML
980 root = XML(_bytes("<root>RTEXT<a></a>ATAIL<b/><c>CTEXT</c>CTAIL</root>"))
981
982 text = list(root[2].itertext())
983 self.assertEqual(["CTEXT"],
984 text)
985
987 XML = self.etree.XML
988 root = XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))
989 self.assertEqual(len(list(root.findall("c"))), 1)
990 self.assertEqual(len(list(root.findall(".//c"))), 2)
991 self.assertEqual(len(list(root.findall(".//b"))), 3)
992 self.assertEqual(len(list(root.findall(".//b"))[0]), 1)
993 self.assertEqual(len(list(root.findall(".//b"))[1]), 0)
994 self.assertEqual(len(list(root.findall(".//b"))[2]), 0)
995
997 XML = self.etree.XML
998 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
999 self.assertEqual(len(list(root.findall(".//{X}b"))), 2)
1000 self.assertEqual(len(list(root.findall(".//b"))), 3)
1001 self.assertEqual(len(list(root.findall("b"))), 2)
1002
1003 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
1007
1008 root = self.etree.XML('''
1009 <a xmlns:x="X" xmlns:y="Y">
1010 <x:b><c/></x:b>
1011 <b/>
1012 <c><x:b/><b/></c><y:b/>
1013 </a>''')
1014 root.append(self.etree.Comment('test'))
1015
1016 self.assertEqual(summarize_list(root.findall("{*}b")),
1017 ['{X}b', 'b', '{Y}b'])
1018 self.assertEqual(summarize_list(root.findall("{*}c")),
1019 ['c'])
1020 self.assertEqual(summarize_list(root.findall("{X}*")),
1021 ['{X}b'])
1022 self.assertEqual(summarize_list(root.findall("{Y}*")),
1023 ['{Y}b'])
1024 self.assertEqual(summarize_list(root.findall("{}*")),
1025 ['b', 'c'])
1026 self.assertEqual(summarize_list(root.findall("{}b")), # only for consistency
1027 ['b'])
1028 self.assertEqual(summarize_list(root.findall("{}b")),
1029 summarize_list(root.findall("b")))
1030 self.assertEqual(summarize_list(root.findall("{*}*")),
1031 ['{X}b', 'b', 'c', '{Y}b'])
1032 self.assertEqual(summarize_list(root.findall("{*}*")
1033 + ([] if self.etree is etree else [root[-1]])),
1034 summarize_list(root.findall("*")))
1035
1036 self.assertEqual(summarize_list(root.findall(".//{*}b")),
1037 ['{X}b', 'b', '{X}b', 'b', '{Y}b'])
1038 self.assertEqual(summarize_list(root.findall(".//{*}c")),
1039 ['c', 'c'])
1040 self.assertEqual(summarize_list(root.findall(".//{X}*")),
1041 ['{X}b', '{X}b'])
1042 self.assertEqual(summarize_list(root.findall(".//{Y}*")),
1043 ['{Y}b'])
1044 self.assertEqual(summarize_list(root.findall(".//{}*")),
1045 ['c', 'b', 'c', 'b'])
1046 self.assertEqual(summarize_list(root.findall(".//{}b")),
1047 ['b', 'b'])
1048
1050 Element = self.etree.Element
1051
1052 el = Element('tag', foo='Foo', bar='Bar')
1053 self.assertEqual('Foo', el.attrib['foo'])
1054 self.assertEqual('Bar', el.attrib['bar'])
1055
1057 Element = self.etree.Element
1058
1059 el = Element('tag', {'foo': 'Foo', 'bar': 'Bar'})
1060 self.assertEqual('Foo', el.attrib['foo'])
1061 self.assertEqual('Bar', el.attrib['bar'])
1062
1064 Element = self.etree.Element
1065
1066 el = Element('tag', {'foo': 'Foo', 'bar': 'Bar'}, baz='Baz')
1067 self.assertEqual('Foo', el.attrib['foo'])
1068 self.assertEqual('Bar', el.attrib['bar'])
1069 self.assertEqual('Baz', el.attrib['baz'])
1070
1072 Element = self.etree.Element
1073
1074 el = Element('tag', {'foo': 'Foo', 'bar': 'Bar'}, bar='Baz')
1075 self.assertEqual('Foo', el.attrib['foo'])
1076 self.assertEqual('Baz', el.attrib['bar'])
1077
1079 Element = self.etree.Element
1080
1081 el = Element('tag', {'{ns1}foo':'Foo', '{ns2}bar':'Bar'})
1082 self.assertEqual('Foo', el.attrib['{ns1}foo'])
1083 self.assertEqual('Bar', el.attrib['{ns2}bar'])
1084
1086 Element = self.etree.Element
1087 SubElement = self.etree.SubElement
1088
1089 el = Element('tag')
1090 SubElement(el, 'foo', {'foo':'Foo'}, baz="Baz")
1091 self.assertEqual("Baz", el[0].attrib['baz'])
1092 self.assertEqual('Foo', el[0].attrib['foo'])
1093
1095 Element = self.etree.Element
1096 SubElement = self.etree.SubElement
1097
1098 el = Element('tag')
1099 SubElement(el, 'foo', {'{ns1}foo':'Foo', '{ns2}bar':'Bar'})
1100 self.assertEqual('Foo', el[0].attrib['{ns1}foo'])
1101 self.assertEqual('Bar', el[0].attrib['{ns2}bar'])
1102
1104 ElementTree = self.etree.ElementTree
1105 XML = self.etree.XML
1106
1107 for i in range(10):
1108 f = BytesIO()
1109 root = XML(_bytes('<doc%s>This is a test.</doc%s>' % (i, i)))
1110 tree = ElementTree(element=root)
1111 tree.write(f)
1112 data = f.getvalue()
1113 self.assertEqual(
1114 _bytes('<doc%s>This is a test.</doc%s>' % (i, i)),
1115 canonicalize(data))
1116
1117 required_versions_ET['test_write_method_html'] = (1,3)
1119 ElementTree = self.etree.ElementTree
1120 Element = self.etree.Element
1121 SubElement = self.etree.SubElement
1122
1123 html = Element('html')
1124 body = SubElement(html, 'body')
1125 p = SubElement(body, 'p')
1126 p.text = "html"
1127 SubElement(p, 'br').tail = "test"
1128
1129 tree = ElementTree(element=html)
1130 f = BytesIO()
1131 tree.write(f, method="html")
1132 data = f.getvalue().replace(_bytes('\n'),_bytes(''))
1133
1134 self.assertEqual(_bytes('<html><body><p>html<br>test</p></body></html>'),
1135 data)
1136
1137 required_versions_ET['test_write_method_text'] = (1,3)
1139 ElementTree = self.etree.ElementTree
1140 Element = self.etree.Element
1141 SubElement = self.etree.SubElement
1142
1143 a = Element('a')
1144 a.text = "A"
1145 a.tail = "tail"
1146 b = SubElement(a, 'b')
1147 b.text = "B"
1148 b.tail = "TAIL"
1149 c = SubElement(a, 'c')
1150 c.text = "C"
1151
1152 tree = ElementTree(element=a)
1153 f = BytesIO()
1154 tree.write(f, method="text")
1155 data = f.getvalue()
1156
1157 self.assertEqual(_bytes('ABTAILCtail'),
1158 data)
1159
1161 ElementTree = self.etree.ElementTree
1162 XML = self.etree.XML
1163
1164 tree = ElementTree( XML(_bytes('<doc>This is a test.</doc>')) )
1165 self.assertRaises(IOError, tree.write,
1166 "definitely////\\-\\nonexisting\\-\\////FILE")
1167
1168 # this could trigger a crash, apparently because the document
1169 # reference was prematurely garbage collected
1171 Element = self.etree.Element
1172
1173 element = Element('tag')
1174 for i in range(10):
1175 element.attrib['key'] = 'value'
1176 value = element.attrib['key']
1177 self.assertEqual(value, 'value')
1178
1179 # from doctest; for some reason this caused crashes too
1181 Element = self.etree.Element
1182 ElementTree = self.etree.ElementTree
1183
1184 f = BytesIO()
1185 for i in range(10):
1186 element = Element('tag%s' % i)
1187 self._check_element(element)
1188 tree = ElementTree(element)
1189 tree.write(f)
1190 self._check_element_tree(tree)
1191
1193 Element = self.etree.Element
1194 SubElement = self.etree.SubElement
1195
1196 el = Element('foo')
1197 el2 = SubElement(el, 'bar')
1198 el3 = SubElement(el2, 'baz')
1199
1200 al = Element('foo2')
1201 al2 = SubElement(al, 'bar2')
1202 al3 = SubElement(al2, 'baz2')
1203
1204 # now move al2 into el
1205 el.append(al2)
1206
1207 # now change al3 directly
1208 al3.text = 'baz2-modified'
1209
1210 # it should have changed through this route too
1211 self.assertEqual(
1212 'baz2-modified',
1213 el[1][0].text)
1214
1216 Element = self.etree.Element
1217 SubElement = self.etree.SubElement
1218
1219 a = Element('a')
1220 b = SubElement(a, 'b')
1221 a.text = 'hoi'
1222 self.assertEqual(
1223 'hoi',
1224 a.text)
1225 self.assertEqual(
1226 'b',
1227 a[0].tag)
1228
1230 Element = self.etree.Element
1231 SubElement = self.etree.SubElement
1232
1233 a = Element('a')
1234 a.text = 'hoi'
1235 b = SubElement(a ,'b')
1236 self.assertEqual(
1237 'hoi',
1238 a.text)
1239 self.assertEqual(
1240 'b',
1241 a[0].tag)
1242
1244 Element = self.etree.Element
1245
1246 a = Element('a')
1247
1248 a.text = 'foo'
1249 a.text = None
1250
1251 self.assertEqual(
1252 None,
1253 a.text)
1254 self.assertXML(_bytes('<a></a>'), a)
1255
1257 Element = self.etree.Element
1258
1259 a = Element('a')
1260 self.assertEqual(None, a.text)
1261
1262 a.text = ''
1263 self.assertEqual('', a.text)
1264 self.assertXML(_bytes('<a></a>'), a)
1265
1267 Element = self.etree.Element
1268 SubElement = self.etree.SubElement
1269
1270 a = Element('a')
1271 a.tail = 'dag'
1272 self.assertEqual('dag',
1273 a.tail)
1274 b = SubElement(a, 'b')
1275 b.tail = 'hoi'
1276 self.assertEqual('hoi',
1277 b.tail)
1278 self.assertEqual('dag',
1279 a.tail)
1280
1282 Element = self.etree.Element
1283
1284 a = Element('a')
1285 b = Element('b')
1286 b.tail = 'b_tail'
1287 a.append(b)
1288 self.assertEqual('b_tail',
1289 b.tail)
1290
1292 Element = self.etree.Element
1293 SubElement = self.etree.SubElement
1294
1295 a = Element('a')
1296 b = SubElement(a, 'b')
1297 b.tail = 'foo'
1298 b.tail = 'bar'
1299 self.assertEqual('bar',
1300 b.tail)
1301 self.assertXML(_bytes('<a><b></b>bar</a>'), a)
1302
1304 Element = self.etree.Element
1305 a = Element('a')
1306 a.tail = 'foo'
1307 a.tail = None
1308 self.assertEqual(
1309 None,
1310 a.tail)
1311 self.assertXML(_bytes('<a></a>'), a)
1312
1313 required_versions_ET['test_extend'] = (1,3)
1315 root = self.etree.Element('foo')
1316 for i in range(3):
1317 element = self.etree.SubElement(root, 'a%s' % i)
1318 element.text = "text%d" % i
1319 element.tail = "tail%d" % i
1320
1321 elements = []
1322 for i in range(3):
1323 new_element = self.etree.Element("test%s" % i)
1324 new_element.text = "TEXT%s" % i
1325 new_element.tail = "TAIL%s" % i
1326 elements.append(new_element)
1327
1328 root.extend(elements)
1329
1330 self.assertEqual(
1331 ["a0", "a1", "a2", "test0", "test1", "test2"],
1332 [ el.tag for el in root ])
1333 self.assertEqual(
1334 ["text0", "text1", "text2", "TEXT0", "TEXT1", "TEXT2"],
1335 [ el.text for el in root ])
1336 self.assertEqual(
1337 ["tail0", "tail1", "tail2", "TAIL0", "TAIL1", "TAIL2"],
1338 [ el.tail for el in root ])
1339
1341 Element = self.etree.Element
1342 SubElement = self.etree.SubElement
1343 Comment = self.etree.Comment
1344
1345 a = Element('a')
1346 a.append(Comment('foo'))
1347 self.assertEqual(a[0].tag, Comment)
1348 self.assertEqual(a[0].text, 'foo')
1349
1350 # ElementTree < 1.3 adds whitespace around comments
1351 required_versions_ET['test_comment_text'] = (1,3)
1353 Element = self.etree.Element
1354 SubElement = self.etree.SubElement
1355 Comment = self.etree.Comment
1356 tostring = self.etree.tostring
1357
1358 a = Element('a')
1359 a.append(Comment('foo'))
1360 self.assertEqual(a[0].text, 'foo')
1361
1362 self.assertEqual(
1363 _bytes('<a><!--foo--></a>'),
1364 tostring(a))
1365
1366 a[0].text = "TEST"
1367 self.assertEqual(a[0].text, 'TEST')
1368
1369 self.assertEqual(
1370 _bytes('<a><!--TEST--></a>'),
1371 tostring(a))
1372
1373 # ElementTree < 1.3 adds whitespace around comments
1374 required_versions_ET['test_comment_whitespace'] = (1,3)
1376 Element = self.etree.Element
1377 SubElement = self.etree.SubElement
1378 Comment = self.etree.Comment
1379 tostring = self.etree.tostring
1380
1381 a = Element('a')
1382 a.append(Comment(' foo '))
1383 self.assertEqual(a[0].text, ' foo ')
1384 self.assertEqual(
1385 _bytes('<a><!-- foo --></a>'),
1386 tostring(a))
1387
1389 Comment = self.etree.Comment
1390 c = Comment('foo')
1391 self.assertEqual({}, c.attrib)
1392 self.assertEqual([], list(c.keys()))
1393 self.assertEqual([], list(c.items()))
1394 self.assertEqual(None, c.get('hoi'))
1395 self.assertEqual(0, len(c))
1396 # should not iterate
1397 for i in c:
1398 pass
1399
1401 # lxml.etree separates target and text
1402 Element = self.etree.Element
1403 SubElement = self.etree.SubElement
1404 ProcessingInstruction = self.etree.ProcessingInstruction
1405
1406 a = Element('a')
1407 a.append(ProcessingInstruction('foo', 'some more text'))
1408 self.assertEqual(a[0].tag, ProcessingInstruction)
1409 self.assertXML(_bytes("<a><?foo some more text?></a>"),
1410 a)
1411
1413 # lxml.etree separates target and text
1414 Element = self.etree.Element
1415 SubElement = self.etree.SubElement
1416 ProcessingInstruction = self.etree.PI
1417
1418 a = Element('a')
1419 a.append(ProcessingInstruction('foo', 'some more text'))
1420 self.assertEqual(a[0].tag, ProcessingInstruction)
1421 self.assertXML(_bytes("<a><?foo some more text?></a>"),
1422 a)
1423
1425 ProcessingInstruction = self.etree.ProcessingInstruction
1426 pi = ProcessingInstruction('foo')
1427 self.assertEqual({}, pi.attrib)
1428 self.assertEqual([], list(pi.keys()))
1429 self.assertEqual([], list(pi.items()))
1430 self.assertEqual(None, pi.get('hoi'))
1431 self.assertEqual(0, len(pi))
1432 # should not iterate
1433 for i in pi:
1434 pass
1435
1437 Element = self.etree.Element
1438 SubElement = self.etree.SubElement
1439
1440 a = Element('a')
1441 b = SubElement(a, 'b')
1442 c = Element('c')
1443 a[0] = c
1444 self.assertEqual(
1445 c,
1446 a[0])
1447 self.assertXML(_bytes('<a><c></c></a>'),
1448 a)
1449 self.assertXML(_bytes('<b></b>'),
1450 b)
1451
1453 Element = self.etree.Element
1454 SubElement = self.etree.SubElement
1455
1456 a = Element('a')
1457 for i in range(5):
1458 b = SubElement(a, 'b%s' % i)
1459 c = SubElement(b, 'c')
1460 for i in range(5):
1461 d = Element('d')
1462 e = SubElement(d, 'e')
1463 a[i] = d
1464 self.assertXML(
1465 _bytes('<a><d><e></e></d><d><e></e></d><d><e></e></d><d><e></e></d><d><e></e></d></a>'),
1466 a)
1467 self.assertXML(_bytes('<c></c>'),
1468 c)
1469
1471 Element = self.etree.Element
1472 SubElement = self.etree.SubElement
1473
1474 a = Element('a')
1475 SubElement(a, 'b')
1476 d = Element('d')
1477 a[0] = d
1478 self.assertXML(_bytes('<a><d></d></a>'), a)
1479
1481 Element = self.etree.Element
1482 SubElement = self.etree.SubElement
1483
1484 a = Element('a')
1485 b = SubElement(a, 'b')
1486
1487 self.assertRaises(IndexError, operator.setitem, a, 1, Element('c'))
1488
1490 Element = self.etree.Element
1491 SubElement = self.etree.SubElement
1492
1493 a = Element('a')
1494 b = SubElement(a, 'b')
1495 b.tail = 'B2'
1496 c = Element('c')
1497 c.tail = 'C2'
1498
1499 a[0] = c
1500 self.assertXML(
1501 _bytes('<a><c></c>C2</a>'),
1502 a)
1503
1505 Element = self.etree.Element
1506 SubElement = self.etree.SubElement
1507
1508 a = Element('a')
1509 b = SubElement(a, 'b')
1510
1511 a.tag = 'c'
1512
1513 self.assertEqual(
1514 'c',
1515 a.tag)
1516
1517 self.assertXML(
1518 _bytes('<c><b></b></c>'),
1519 a)
1520
1522 Element = self.etree.Element
1523 SubElement = self.etree.SubElement
1524 tostring = self.etree.tostring
1525
1526 a = Element('{a}a')
1527 b1 = SubElement(a, '{a}b')
1528 b2 = SubElement(a, '{b}b')
1529
1530 self.assertEqual('{a}b', b1.tag)
1531
1532 b1.tag = 'c'
1533
1534 # can't use C14N here!
1535 self.assertEqual('c', b1.tag)
1536 self.assertEqual(_bytes('<c'), tostring(b1)[:2])
1537 self.assertTrue(_bytes('<c') in tostring(a))
1538
1540 Element = self.etree.Element
1541 SubElement = self.etree.SubElement
1542 tostring = self.etree.tostring
1543
1544 a = Element('{a}a')
1545 b1 = SubElement(a, '{a}b')
1546 b2 = SubElement(a, '{b}b')
1547
1548 a.tag = 'c'
1549
1550 self.assertEqual(
1551 'c',
1552 a.tag)
1553
1554 # can't use C14N here!
1555 self.assertEqual('c', a.tag)
1556 self.assertEqual(_bytes('<c'), tostring(a)[:2])
1557
1563
1564 a = Element("a")
1565 a.tag = strTest("TAG")
1566 self.assertXML(_bytes('<TAG></TAG>'),
1567 a)
1568
1570 Element = self.etree.Element
1571 SubElement = self.etree.SubElement
1572
1573 a = Element('a')
1574 b = SubElement(a, 'b')
1575 c = SubElement(a, 'c')
1576 d = SubElement(a, 'd')
1577
1578 del a[1]
1579 self.assertXML(
1580 _bytes('<a><b></b><d></d></a>'),
1581 a)
1582
1583 del a[0]
1584 self.assertXML(
1585 _bytes('<a><d></d></a>'),
1586 a)
1587
1588 del a[0]
1589 self.assertXML(
1590 _bytes('<a></a>'),
1591 a)
1592 # move deleted element into other tree afterwards
1593 other = Element('other')
1594 other.append(c)
1595 self.assertXML(
1596 _bytes('<other><c></c></other>'),
1597 other)
1598
1600 Element = self.etree.Element
1601 SubElement = self.etree.SubElement
1602
1603 a = Element('a')
1604 b = SubElement(a, 'b')
1605 bs = SubElement(b, 'bs')
1606 c = SubElement(a, 'c')
1607 cs = SubElement(c, 'cs')
1608
1609 el = a[0]
1610 self.assertXML(
1611 _bytes('<a><b><bs></bs></b><c><cs></cs></c></a>'),
1612 a)
1613 self.assertXML(_bytes('<b><bs></bs></b>'), b)
1614 self.assertXML(_bytes('<c><cs></cs></c>'), c)
1615
1616 del a[0]
1617 self.assertXML(
1618 _bytes('<a><c><cs></cs></c></a>'),
1619 a)
1620 self.assertXML(_bytes('<b><bs></bs></b>'), b)
1621 self.assertXML(_bytes('<c><cs></cs></c>'), c)
1622
1623 a.insert(0, el)
1624 self.assertXML(
1625 _bytes('<a><b><bs></bs></b><c><cs></cs></c></a>'),
1626 a)
1627 self.assertXML(_bytes('<b><bs></bs></b>'), b)
1628 self.assertXML(_bytes('<c><cs></cs></c>'), c)
1629
1631 Element = self.etree.Element
1632 SubElement = self.etree.SubElement
1633
1634 a = Element('a')
1635 b = SubElement(a, 'b')
1636 bs = SubElement(b, 'bs')
1637 c = SubElement(a, 'c')
1638 cs = SubElement(c, 'cs')
1639
1640 el = a[0]
1641 del a[0]
1642 a[0] = el
1643 self.assertXML(
1644 _bytes('<a><b><bs></bs></b></a>'),
1645 a)
1646 self.assertXML(_bytes('<b><bs></bs></b>'), b)
1647 self.assertXML(_bytes('<c><cs></cs></c>'), c)
1648
1650 Element = self.etree.Element
1651 SubElement = self.etree.SubElement
1652
1653 a = Element('a')
1654 b = SubElement(a, 'b')
1655 bs = SubElement(b, 'bs')
1656 c = SubElement(a, 'c')
1657 cs = SubElement(c, 'cs')
1658
1659 el = a[0]
1660 del a[0]
1661 a[0:0] = [el]
1662 self.assertXML(
1663 _bytes('<a><b><bs></bs></b><c><cs></cs></c></a>'),
1664 a)
1665 self.assertXML(_bytes('<b><bs></bs></b>'), b)
1666 self.assertXML(_bytes('<c><cs></cs></c>'), c)
1667
1669 XML = self.etree.XML
1670 a = XML(_bytes('<a><b></b>B2<c></c>C2</a>'))
1671 b, c = a
1672
1673 a[:] = []
1674
1675 self.assertEqual("B2", b.tail)
1676 self.assertEqual("C2", c.tail)
1677
1679 XML = self.etree.XML
1680 root = XML(_bytes(
1681 '<foo><bar xmlns:baz="http://huhu"><puh><baz:bump1 /><baz:bump2 /></puh></bar></foo>'))
1682 root[:] = root.findall('.//puh') # delete bar from hierarchy
1683
1684 # previously, this lost a namespace declaration on bump2
1685 result = self.etree.tostring(root)
1686 foo = self.etree.fromstring(result)
1687
1688 self.assertEqual('puh', foo[0].tag)
1689 self.assertEqual('{http://huhu}bump1', foo[0][0].tag)
1690 self.assertEqual('{http://huhu}bump2', foo[0][1].tag)
1691
1693 ElementTree = self.etree.ElementTree
1694 f = BytesIO('<a><b></b>B2<c></c>C2</a>')
1695 doc = ElementTree(file=f)
1696 a = doc.getroot()
1697 del a[0]
1698 self.assertXML(
1699 _bytes('<a><c></c>C2</a>'),
1700 a)
1701
1703 ElementTree = self.etree.ElementTree
1704 f = BytesIO('<a><b></b>B2<c></c>C2</a>')
1705 doc = ElementTree(file=f)
1706 a = doc.getroot()
1707 b, c = a
1708 del a[0]
1709 self.assertXML(
1710 _bytes('<a><c></c>C2</a>'),
1711 a)
1712 self.assertEqual("B2", b.tail)
1713 self.assertEqual("C2", c.tail)
1714
1716 Element = self.etree.Element
1717
1718 a = Element('a')
1719 a.text = 'foo'
1720 a.tail = 'bar'
1721 a.set('hoi', 'dag')
1722 a.clear()
1723 self.assertEqual(None, a.text)
1724 self.assertEqual(None, a.tail)
1725 self.assertEqual(None, a.get('hoi'))
1726 self.assertEqual('a', a.tag)
1727
1729 Element = self.etree.Element
1730 SubElement = self.etree.SubElement
1731
1732 a = Element('a')
1733 a.text = 'foo'
1734 a.tail = 'bar'
1735 a.set('hoi', 'dag')
1736 b = SubElement(a, 'b')
1737 c = SubElement(b, 'c')
1738 a.clear()
1739 self.assertEqual(None, a.text)
1740 self.assertEqual(None, a.tail)
1741 self.assertEqual(None, a.get('hoi'))
1742 self.assertEqual('a', a.tag)
1743 self.assertEqual(0, len(a))
1744 self.assertXML(_bytes('<a></a>'),
1745 a)
1746 self.assertXML(_bytes('<b><c></c></b>'),
1747 b)
1748
1750 ElementTree = self.etree.ElementTree
1751 f = BytesIO('<a><b></b>B2<c></c>C2</a>')
1752 doc = ElementTree(file=f)
1753 a = doc.getroot()
1754 a.clear()
1755 self.assertXML(
1756 _bytes('<a></a>'),
1757 a)
1758
1760 Element = self.etree.Element
1761 SubElement = self.etree.SubElement
1762
1763 a = Element('a')
1764 b = SubElement(a, 'b')
1765 c = SubElement(a, 'c')
1766 d = Element('d')
1767 a.insert(0, d)
1768
1769 self.assertEqual(
1770 d,
1771 a[0])
1772
1773 self.assertXML(
1774 _bytes('<a><d></d><b></b><c></c></a>'),
1775 a)
1776
1777 e = Element('e')
1778 a.insert(2, e)
1779 self.assertEqual(
1780 e,
1781 a[2])
1782 self.assertXML(
1783 _bytes('<a><d></d><b></b><e></e><c></c></a>'),
1784 a)
1785
1787 # See GH#268 / LP#1773749.
1788 Element = self.etree.Element
1789 SubElement = self.etree.SubElement
1790
1791 # Use unique names to make sure they are new in the tag name dict.
1792 import uuid
1793 names = dict((k, 'tag-' + str(uuid.uuid4())) for k in 'abcde')
1794
1795 a = Element(names['a'])
1796 b = SubElement(a, names['b'])
1797 c = SubElement(a, names['c'])
1798 d = Element(names['d'])
1799 a.insert(0, d)
1800
1801 self.assertEqual(
1802 d,
1803 a[0])
1804
1805 self.assertXML(
1806 _bytes('<%(a)s><%(d)s></%(d)s><%(b)s></%(b)s><%(c)s></%(c)s></%(a)s>' % names),
1807 a)
1808
1809 e = Element(names['e'])
1810 a.insert(2, e)
1811 self.assertEqual(
1812 e,
1813 a[2])
1814 self.assertXML(
1815 _bytes('<%(a)s><%(d)s></%(d)s><%(b)s></%(b)s><%(e)s></%(e)s><%(c)s></%(c)s></%(a)s>' % names),
1816 a)
1817
1819 Element = self.etree.Element
1820 SubElement = self.etree.SubElement
1821
1822 a = Element('a')
1823 b = SubElement(a, 'b')
1824 c = Element('c')
1825
1826 a.insert(2, c)
1827 self.assertEqual(
1828 c,
1829 a[1])
1830 self.assertXML(
1831 _bytes('<a><b></b><c></c></a>'),
1832 a)
1833
1835 Element = self.etree.Element
1836 SubElement = self.etree.SubElement
1837
1838 a = Element('a')
1839 b = SubElement(a, 'b')
1840 c = SubElement(a, 'c')
1841
1842 d = Element('d')
1843 a.insert(-1, d)
1844 self.assertEqual(
1845 d,
1846 a[-2])
1847 self.assertXML(
1848 _bytes('<a><b></b><d></d><c></c></a>'),
1849 a)
1850
1852 Element = self.etree.Element
1853 SubElement = self.etree.SubElement
1854
1855 a = Element('a')
1856 b = SubElement(a, 'b')
1857
1858 c = Element('c')
1859 c.tail = 'C2'
1860
1861 a.insert(0, c)
1862 self.assertXML(
1863 _bytes('<a><c></c>C2<b></b></a>'),
1864 a)
1865
1867 Element = self.etree.Element
1868 SubElement = self.etree.SubElement
1869
1870 a = Element('a')
1871 b = SubElement(a, 'b')
1872 c = SubElement(a, 'c')
1873
1874 a.remove(b)
1875 self.assertEqual(
1876 c,
1877 a[0])
1878 self.assertXML(
1879 _bytes('<a><c></c></a>'),
1880 a)
1881
1883 Element = self.etree.Element
1884 SubElement = self.etree.SubElement
1885
1886 a = Element('{http://test}a')
1887 b = SubElement(a, '{http://test}b')
1888 c = SubElement(a, '{http://test}c')
1889
1890 a.remove(b)
1891 self.assertXML(
1892 _bytes('<ns0:a xmlns:ns0="http://test"><ns0:c></ns0:c></ns0:a>'),
1893 a)
1894 self.assertXML(
1895 _bytes('<ns0:b xmlns:ns0="http://test"></ns0:b>'),
1896 b)
1897
1899 Element = self.etree.Element
1900 SubElement = self.etree.SubElement
1901
1902 a = Element('a')
1903 b = SubElement(a, 'b')
1904 c = SubElement(a, 'c')
1905 d = Element('d')
1906 self.assertRaises(
1907 ValueError, a.remove, d)
1908
1910 Element = self.etree.Element
1911 SubElement = self.etree.SubElement
1912
1913 a = Element('a')
1914 b = SubElement(a, 'b')
1915 b.tail = 'b2'
1916 a.remove(b)
1917 self.assertXML(
1918 _bytes('<a></a>'),
1919 a)
1920 self.assertEqual('b2', b.tail)
1921
1923 # There is no guarantee that this "works", but it should
1924 # remove at least one child and not crash.
1925 Element = self.etree.Element
1926 SubElement = self.etree.SubElement
1927
1928 a = Element('a')
1929 SubElement(a, 'b')
1930 SubElement(a, 'c')
1931 SubElement(a, 'd')
1932 for el in a:
1933 a.remove(el)
1934 self.assertLess(len(a), 3)
1935
1937 Element = self.etree.Element
1938 SubElement = self.etree.SubElement
1939
1940 a = Element('a')
1941 b = SubElement(a, 'b')
1942 c = SubElement(a, 'c')
1943 d = SubElement(b, 'd')
1944 e = SubElement(c, 'e')
1945 self.assertXML(
1946 _bytes('<a><b><d></d></b><c><e></e></c></a>'),
1947 a)
1948 self.assertEqual(
1949 [b, c],
1950 a.getchildren())
1951 self.assertEqual(
1952 [d],
1953 b.getchildren())
1954 self.assertEqual(
1955 [],
1956 d.getchildren())
1957
1959 Element = self.etree.Element
1960
1961 a = Element('a')
1962 b = a.makeelement('c', {'hoi':'dag'})
1963 self.assertXML(
1964 _bytes('<c hoi="dag"></c>'),
1965 b)
1966
1967 required_versions_ET['test_iter'] = (1,3)
1969 Element = self.etree.Element
1970 SubElement = self.etree.SubElement
1971
1972 a = Element('a')
1973 b = SubElement(a, 'b')
1974 c = SubElement(a, 'c')
1975 d = SubElement(b, 'd')
1976 e = SubElement(c, 'e')
1977
1978 self.assertEqual(
1979 [a, b, d, c, e],
1980 list(a.iter()))
1981 self.assertEqual(
1982 [d],
1983 list(d.iter()))
1984
1986 Element = self.etree.Element
1987 SubElement = self.etree.SubElement
1988
1989 a = Element('a')
1990 a.text = 'a'
1991 a.tail = 'a1' * 100
1992 b = SubElement(a, 'b')
1993 b.text = 'b'
1994 b.tail = 'b1' * 100
1995 c = SubElement(a, 'c')
1996 c.text = 'c'
1997 c.tail = 'c1' * 100
1998 d = SubElement(b, 'd')
1999 d.text = 'd'
2000 d.tail = 'd1' * 100
2001 e = SubElement(c, 'e')
2002 e.text = 'e'
2003 e.tail = 'e1' * 100
2004
2005 for el in a.iter():
2006 el.tail = None
2007 el = None
2008
2009 self.assertEqual(
2010 [None] * 5,
2011 [el.tail for el in a.iter()])
2012
2014 Element = self.etree.Element
2015 SubElement = self.etree.SubElement
2016
2017 a = Element('a')
2018 b = SubElement(a, 'b')
2019 c = SubElement(a, 'c')
2020 d = SubElement(b, 'd')
2021 e = SubElement(c, 'e')
2022
2023 self.assertEqual(
2024 [a, b, d, c, e],
2025 list(a.getiterator()))
2026 self.assertEqual(
2027 [d],
2028 list(d.getiterator()))
2029
2031 Element = self.etree.Element
2032 SubElement = self.etree.SubElement
2033
2034 a = Element('a')
2035 b = SubElement(a, 'b')
2036 c = SubElement(a, 'c')
2037 d = SubElement(b, 'd')
2038 e = SubElement(c, 'e')
2039
2040 self.assertEqual(
2041 [],
2042 list(a.getiterator('none')))
2043 self.assertEqual(
2044 [],
2045 list(e.getiterator('none')))
2046 self.assertEqual(
2047 [e],
2048 list(e.getiterator()))
2049
2051 Element = self.etree.Element
2052 SubElement = self.etree.SubElement
2053
2054 a = Element('a')
2055 b = SubElement(a, 'b')
2056 c = SubElement(a, 'c')
2057 d = SubElement(b, 'd')
2058 e = SubElement(c, 'e')
2059
2060 self.assertEqual(
2061 [a],
2062 list(a.getiterator('a')))
2063 a2 = SubElement(e, 'a')
2064 self.assertEqual(
2065 [a, a2],
2066 list(a.getiterator('a')))
2067 self.assertEqual(
2068 [a2],
2069 list(c.getiterator('a')))
2070
2072 Element = self.etree.Element
2073 SubElement = self.etree.SubElement
2074
2075 a = Element('a')
2076 b = SubElement(a, 'b')
2077 c = SubElement(a, 'c')
2078 d = SubElement(b, 'd')
2079 e = SubElement(c, 'e')
2080
2081 self.assertEqual(
2082 [a, b, d, c, e],
2083 list(a.getiterator('*')))
2084
2086 Element = self.etree.Element
2087 Comment = self.etree.Comment
2088 SubElement = self.etree.SubElement
2089
2090 a = Element('a')
2091 b = SubElement(a, 'b')
2092 comment_b = Comment("TEST-b")
2093 b.append(comment_b)
2094
2095 self.assertEqual(
2096 [comment_b],
2097 list(a.getiterator(Comment)))
2098
2099 comment_a = Comment("TEST-a")
2100 a.append(comment_a)
2101
2102 self.assertEqual(
2103 [comment_b, comment_a],
2104 list(a.getiterator(Comment)))
2105
2106 self.assertEqual(
2107 [comment_b],
2108 list(b.getiterator(Comment)))
2109
2111 Element = self.etree.Element
2112 PI = self.etree.ProcessingInstruction
2113 SubElement = self.etree.SubElement
2114
2115 a = Element('a')
2116 b = SubElement(a, 'b')
2117 pi_b = PI("TEST-b")
2118 b.append(pi_b)
2119
2120 self.assertEqual(
2121 [pi_b],
2122 list(a.getiterator(PI)))
2123
2124 pi_a = PI("TEST-a")
2125 a.append(pi_a)
2126
2127 self.assertEqual(
2128 [pi_b, pi_a],
2129 list(a.getiterator(PI)))
2130
2131 self.assertEqual(
2132 [pi_b],
2133 list(b.getiterator(PI)))
2134
2136 Element = self.etree.Element
2137 SubElement = self.etree.SubElement
2138
2139 a = Element('a')
2140 a.text = 'a'
2141 b = SubElement(a, 'b')
2142 b.text = 'b'
2143 b.tail = 'b1'
2144 c = SubElement(a, 'c')
2145 c.text = 'c'
2146 c.tail = 'c1'
2147 d = SubElement(b, 'd')
2148 d.text = 'd'
2149 d.tail = 'd1'
2150 e = SubElement(c, 'e')
2151 e.text = 'e'
2152 e.tail = 'e1'
2153
2154 self.assertEqual(
2155 [a, b, d, c, e],
2156 list(a.getiterator()))
2157 #self.assertEqual(
2158 # [d],
2159 # list(d.getiterator()))
2160
2162 Element = self.etree.Element
2163 SubElement = self.etree.SubElement
2164
2165 a = Element('a')
2166 a.text = 'a'
2167 b = SubElement(a, 'b')
2168 b.text = 'b'
2169 b.tail = 'b1'
2170 c = SubElement(a, 'c')
2171 c.text = 'c'
2172 c.tail = 'c1'
2173 d = SubElement(b, 'd')
2174 d.text = 'd'
2175 d.tail = 'd1'
2176 e = SubElement(c, 'e')
2177 e.text = 'e'
2178 e.tail = 'e1'
2179
2180 self.assertEqual(
2181 [a],
2182 list(a.getiterator('a')))
2183 a2 = SubElement(e, 'a')
2184 self.assertEqual(
2185 [a, a2],
2186 list(a.getiterator('a')))
2187 self.assertEqual(
2188 [a2],
2189 list(e.getiterator('a')))
2190
2192 Element = self.etree.Element
2193 SubElement = self.etree.SubElement
2194
2195 a = Element('a')
2196 b = SubElement(a, 'b')
2197 c = SubElement(a, 'c')
2198 d = SubElement(a, 'd')
2199
2200 self.assertEqual(
2201 [b, c],
2202 a[0:2])
2203 self.assertEqual(
2204 [b, c, d],
2205 a[:])
2206 self.assertEqual(
2207 [b, c, d],
2208 a[:10])
2209 self.assertEqual(
2210 [b],
2211 a[0:1])
2212 self.assertEqual(
2213 [],
2214 a[10:12])
2215
2217 Element = self.etree.Element
2218 SubElement = self.etree.SubElement
2219
2220 a = Element('a')
2221 b = SubElement(a, 'b')
2222 c = SubElement(a, 'c')
2223 d = SubElement(a, 'd')
2224
2225 self.assertEqual(
2226 [d],
2227 a[-1:])
2228 self.assertEqual(
2229 [c, d],
2230 a[-2:])
2231 self.assertEqual(
2232 [c],
2233 a[-2:-1])
2234 self.assertEqual(
2235 [b, c],
2236 a[-3:-1])
2237 self.assertEqual(
2238 [b, c],
2239 a[-3:2])
2240
2242 Element = self.etree.Element
2243 SubElement = self.etree.SubElement
2244
2245 a = Element('a')
2246 b = SubElement(a, 'b')
2247 c = SubElement(a, 'c')
2248 d = SubElement(a, 'd')
2249 e = SubElement(a, 'e')
2250
2251 self.assertEqual(
2252 [e,d,c,b],
2253 a[::-1])
2254 self.assertEqual(
2255 [b,d],
2256 a[::2])
2257 self.assertEqual(
2258 [e,c],
2259 a[::-2])
2260 self.assertEqual(
2261 [d,c],
2262 a[-2:0:-1])
2263 self.assertEqual(
2264 [e],
2265 a[:1:-2])
2266
2268 ElementTree = self.etree.ElementTree
2269
2270 f = BytesIO('<a><b>B</b>B1<c>C</c>C1</a>')
2271 doc = ElementTree(file=f)
2272 a = doc.getroot()
2273 b = a[0]
2274 c = a[1]
2275 self.assertEqual(
2276 [b, c],
2277 a[:])
2278 self.assertEqual(
2279 [b],
2280 a[0:1])
2281 self.assertEqual(
2282 [c],
2283 a[1:])
2284
2286 Element = self.etree.Element
2287 Comment = self.etree.Comment
2288 SubElement = self.etree.SubElement
2289
2290 a = Element('a')
2291 b = SubElement(a, 'b')
2292 foo = Comment('foo')
2293 a.append(foo)
2294 c = SubElement(a, 'c')
2295 self.assertEqual(
2296 [b, foo, c],
2297 a[:])
2298 self.assertEqual(
2299 foo,
2300 a[1])
2301 a[1] = new = Element('new')
2302 self.assertEqual(
2303 new,
2304 a[1])
2305 self.assertXML(
2306 _bytes('<a><b></b><new></new><c></c></a>'),
2307 a)
2308
2310 Element = self.etree.Element
2311 SubElement = self.etree.SubElement
2312
2313 a = Element('a')
2314 b = SubElement(a, 'b')
2315 c = SubElement(a, 'c')
2316 d = SubElement(a, 'd')
2317 e = SubElement(a, 'e')
2318
2319 del a[1:3]
2320 self.assertEqual(
2321 [b, e],
2322 list(a))
2323
2325 Element = self.etree.Element
2326 SubElement = self.etree.SubElement
2327
2328 a = Element('a')
2329 b = SubElement(a, 'b')
2330 c = SubElement(a, 'c')
2331 d = SubElement(a, 'd')
2332 e = SubElement(a, 'e')
2333
2334 del a[1:-1]
2335 self.assertEqual(
2336 [b, e],
2337 list(a))
2338
2340 Element = self.etree.Element
2341 SubElement = self.etree.SubElement
2342
2343 a = Element('a')
2344 b = SubElement(a, 'b')
2345 c = SubElement(a, 'c')
2346 d = SubElement(a, 'd')
2347 e = SubElement(a, 'e')
2348
2349 del a[-3:-1]
2350 self.assertEqual(
2351 [b, e],
2352 list(a))
2353
2355 Element = self.etree.Element
2356 SubElement = self.etree.SubElement
2357
2358 a = Element('a')
2359 b = SubElement(a, 'b')
2360 c = SubElement(a, 'c')
2361 d = SubElement(a, 'd')
2362 e = SubElement(a, 'e')
2363
2364 del a[1::2]
2365 self.assertEqual(
2366 [b, d],
2367 list(a))
2368
2370 Element = self.etree.Element
2371 SubElement = self.etree.SubElement
2372
2373 a = Element('a')
2374 b = SubElement(a, 'b')
2375 c = SubElement(a, 'c')
2376 d = SubElement(a, 'd')
2377 e = SubElement(a, 'e')
2378
2379 del a[::-1]
2380 self.assertEqual(
2381 [],
2382 list(a))
2383
2385 Element = self.etree.Element
2386 SubElement = self.etree.SubElement
2387
2388 a = Element('a')
2389 b = SubElement(a, 'b')
2390 c = SubElement(a, 'c')
2391 d = SubElement(a, 'd')
2392 e = SubElement(a, 'e')
2393
2394 del a[::-2]
2395 self.assertEqual(
2396 [b, d],
2397 list(a))
2398
2400 ElementTree = self.etree.ElementTree
2401 f = BytesIO('<a><b></b>B2<c></c>C2<d></d>D2<e></e>E2</a>')
2402 doc = ElementTree(file=f)
2403 a = doc.getroot()
2404 del a[1:3]
2405 self.assertXML(
2406 _bytes('<a><b></b>B2<e></e>E2</a>'),
2407 a)
2408
2410 ElementTree = self.etree.ElementTree
2411 f = BytesIO('<a><b></b>B2<c></c>C2<d></d>D2<e></e>E2</a>')
2412 doc = ElementTree(file=f)
2413 a = doc.getroot()
2414 b, c, d, e = a
2415 del a[1:3]
2416 self.assertXML(
2417 _bytes('<a><b></b>B2<e></e>E2</a>'),
2418 a)
2419 self.assertEqual("B2", b.tail)
2420 self.assertEqual("C2", c.tail)
2421 self.assertEqual("D2", d.tail)
2422 self.assertEqual("E2", e.tail)
2423
2425 XML = self.etree.XML
2426 a = XML(_bytes('<a><b></b>B2<c></c>C2</a>'))
2427 b, c = a
2428
2429 del a[:]
2430
2431 self.assertEqual("B2", b.tail)
2432 self.assertEqual("C2", c.tail)
2433
2435 # this could trigger a crash
2436 Element = self.etree.Element
2437 SubElement = self.etree.SubElement
2438 a = Element('a')
2439 b = SubElement(a, 'b')
2440 c = SubElement(b, 'c')
2441 del b # no more reference to b
2442 del a[:]
2443 self.assertEqual('c', c.tag)
2444
2446 Element = self.etree.Element
2447 SubElement = self.etree.SubElement
2448
2449 a = Element('a')
2450 b = SubElement(a, 'b')
2451 c = SubElement(a, 'c')
2452 d = SubElement(a, 'd')
2453
2454 e = Element('e')
2455 f = Element('f')
2456 g = Element('g')
2457
2458 s = [e, f, g]
2459 a[1:2] = s
2460 self.assertEqual(
2461 [b, e, f, g, d],
2462 list(a))
2463
2465 Element = self.etree.Element
2466 SubElement = self.etree.SubElement
2467
2468 a = Element('a')
2469 b = SubElement(a, 'b')
2470 c = SubElement(a, 'c')
2471
2472 e = Element('e')
2473 f = Element('f')
2474 g = Element('g')
2475
2476 s = [e, f, g]
2477 a[:] = s
2478 self.assertEqual(
2479 [e, f, g],
2480 list(a))
2481
2483 Element = self.etree.Element
2484 SubElement = self.etree.SubElement
2485
2486 a = Element('a')
2487
2488 e = Element('e')
2489 f = Element('f')
2490 g = Element('g')
2491
2492 s = [e, f, g]
2493 a[:] = s
2494 self.assertEqual(
2495 [e, f, g],
2496 list(a))
2497
2499 Element = self.etree.Element
2500 SubElement = self.etree.SubElement
2501
2502 a = Element('a')
2503 b = SubElement(a, 'b')
2504 c = SubElement(a, 'c')
2505 d = SubElement(a, 'd')
2506
2507 s = [b, c, d]
2508 a[:] = s
2509 self.assertEqual(
2510 [b, c, d],
2511 list(a))
2512
2514 Element = self.etree.Element
2515 SubElement = self.etree.SubElement
2516
2517 a = Element('a')
2518 b = SubElement(a, 'b')
2519 c = SubElement(a, 'c')
2520 d = SubElement(a, 'd')
2521
2522 s = [d, c, b]
2523 a[:] = s
2524 self.assertEqual(
2525 [d, c, b],
2526 list(a))
2527
2529 Element = self.etree.Element
2530 SubElement = self.etree.SubElement
2531
2532 a = Element('{ns}a')
2533 b = SubElement(a, '{ns}b', {'{ns1}a1': 'test'})
2534 c = SubElement(a, '{ns}c', {'{ns2}a2': 'test'})
2535 d = SubElement(a, '{ns}d', {'{ns3}a3': 'test'})
2536
2537 s = [d, c, b]
2538 a[:] = s
2539 self.assertEqual(
2540 [d, c, b],
2541 list(a))
2542 self.assertEqual(
2543 ['{ns}d', '{ns}c', '{ns}b'],
2544 [ child.tag for child in a ])
2545
2546 self.assertEqual(
2547 [['{ns3}a3'], ['{ns2}a2'], ['{ns1}a1']],
2548 [ list(child.attrib.keys()) for child in a ])
2549
2551 Element = self.etree.Element
2552 SubElement = self.etree.SubElement
2553
2554 a = Element('{ns}a')
2555 b = SubElement(a, '{ns1}b', {'{ns}a1': 'test'})
2556 c = SubElement(a, '{ns2}c', {'{ns}a2': 'test'})
2557 d = SubElement(a, '{ns3}d', {'{ns}a3': 'test'})
2558
2559 s = [d, c, b]
2560 a[:] = s
2561 self.assertEqual(
2562 [d, c, b],
2563 list(a))
2564 self.assertEqual(
2565 ['{ns3}d', '{ns2}c', '{ns1}b'],
2566 [ child.tag for child in a ])
2567
2568 self.assertEqual(
2569 [['{ns}a3'], ['{ns}a2'], ['{ns}a1']],
2570 [ list(child.attrib.keys()) for child in a ])
2571
2573 Element = self.etree.Element
2574 SubElement = self.etree.SubElement
2575
2576 a = Element('a')
2577 b = SubElement(a, 'b')
2578 c = SubElement(a, 'c')
2579
2580 e = Element('e')
2581 f = Element('f')
2582 g = Element('g')
2583 h = Element('h')
2584
2585 s = [e, f]
2586 a[99:] = s
2587 self.assertEqual(
2588 [b, c, e, f],
2589 list(a))
2590
2591 s = [g, h]
2592 a[:0] = s
2593 self.assertEqual(
2594 [g, h, b, c, e, f],
2595 list(a))
2596
2598 Element = self.etree.Element
2599 SubElement = self.etree.SubElement
2600
2601 a = Element('a')
2602 b = SubElement(a, 'b')
2603 c = SubElement(a, 'c')
2604 d = SubElement(a, 'd')
2605
2606 e = Element('e')
2607 f = Element('f')
2608 g = Element('g')
2609
2610 s = [e, f, g]
2611 a[3:] = s
2612 self.assertEqual(
2613 [b, c, d, e, f, g],
2614 list(a))
2615
2617 Element = self.etree.Element
2618 SubElement = self.etree.SubElement
2619
2620 a = Element('a')
2621 b = SubElement(a, 'b')
2622 c = SubElement(a, 'c')
2623
2624 e = Element('e')
2625 f = Element('f')
2626
2627 s = [e]
2628 a[0:1] = s
2629 self.assertEqual(
2630 [e, c],
2631 list(a))
2632
2633 s = [f]
2634 a[1:2] = s
2635 self.assertEqual(
2636 [e, f],
2637 list(a))
2638
2640 ElementTree = self.etree.ElementTree
2641 Element = self.etree.Element
2642 f = BytesIO('<a><b></b>B2<c></c>C2<d></d>D2<e></e>E2</a>')
2643 doc = ElementTree(file=f)
2644 a = doc.getroot()
2645 x = Element('x')
2646 y = Element('y')
2647 z = Element('z')
2648 x.tail = 'X2'
2649 y.tail = 'Y2'
2650 z.tail = 'Z2'
2651 a[1:3] = [x, y, z]
2652 self.assertXML(
2653 _bytes('<a><b></b>B2<x></x>X2<y></y>Y2<z></z>Z2<e></e>E2</a>'),
2654 a)
2655
2657 Element = self.etree.Element
2658 SubElement = self.etree.SubElement
2659
2660 a = Element('a')
2661 b = SubElement(a, 'b')
2662 c = SubElement(a, 'c')
2663 d = SubElement(a, 'd')
2664
2665 x = Element('x')
2666 y = Element('y')
2667
2668 a[1:-1] = [x, y]
2669 self.assertEqual(
2670 [b, x, y, d],
2671 list(a))
2672
2674 Element = self.etree.Element
2675 SubElement = self.etree.SubElement
2676
2677 a = Element('a')
2678 b = SubElement(a, 'b')
2679 c = SubElement(a, 'c')
2680 d = SubElement(a, 'd')
2681
2682 x = Element('x')
2683 y = Element('y')
2684
2685 a[1:-2] = [x, y]
2686 self.assertEqual(
2687 [b, x, y, c, d],
2688 list(a))
2689
2691 Element = self.etree.Element
2692
2693 a = Element('a')
2694
2695 b = Element('b')
2696 c = Element('c')
2697
2698 a[:] = [b, c]
2699 self.assertEqual(
2700 [b, c],
2701 list(a))
2702
2704 Element = self.etree.Element
2705 ElementTree = self.etree.ElementTree
2706
2707 a = Element('a')
2708 a.tail = 'A2'
2709 t = ElementTree(element=a)
2710 self.assertEqual('A2',
2711 a.tail)
2712
2714 Element = self.etree.Element
2715 SubElement = self.etree.SubElement
2716 ElementTree = self.etree.ElementTree
2717
2718 a = Element('a')
2719 b = SubElement(a, 'b')
2720 c = SubElement(a, 'c')
2721 d = SubElement(b, 'd')
2722 e = SubElement(c, 'e')
2723 t = ElementTree(element=a)
2724
2725 self.assertEqual(
2726 [a, b, d, c, e],
2727 list(t.getiterator()))
2728
2730 Element = self.etree.Element
2731 SubElement = self.etree.SubElement
2732 ElementTree = self.etree.ElementTree
2733 a = Element('a')
2734 b = SubElement(a, 'b')
2735 c = SubElement(a, 'c')
2736 d = SubElement(b, 'd')
2737 e = SubElement(c, 'e')
2738 t = ElementTree(element=a)
2739
2740 self.assertEqual(
2741 [a],
2742 list(t.getiterator('a')))
2743 a2 = SubElement(e, 'a')
2744 self.assertEqual(
2745 [a, a2],
2746 list(t.getiterator('a')))
2747
2749 ElementTree = self.etree.ElementTree
2750 ns = 'http://xml.infrae.com/1'
2751 f = BytesIO('<x:a xmlns:x="%s"><x:b></x:b></x:a>' % ns)
2752 t = ElementTree(file=f)
2753 a = t.getroot()
2754 self.assertEqual('{%s}a' % ns,
2755 a.tag)
2756 self.assertEqual('{%s}b' % ns,
2757 a[0].tag)
2758
2760 ElementTree = self.etree.ElementTree
2761 ns = 'http://xml.infrae.com/1'
2762 ns2 = 'http://xml.infrae.com/2'
2763 f = BytesIO('<x:a xmlns:x="%s" xmlns:y="%s"><x:b></x:b><y:b></y:b></x:a>' % (ns, ns2))
2764 t = ElementTree(file=f)
2765 a = t.getroot()
2766 self.assertEqual('{%s}a' % ns,
2767 a.tag)
2768 self.assertEqual('{%s}b' % ns,
2769 a[0].tag)
2770 self.assertEqual('{%s}b' % ns2,
2771 a[1].tag)
2772
2774 Element = self.etree.Element
2775 SubElement = self.etree.SubElement
2776 ns = 'http://xml.infrae.com/1'
2777 ns2 = 'http://xml.infrae.com/2'
2778 a = Element('{%s}a' % ns)
2779 b = SubElement(a, '{%s}b' % ns2)
2780 c = SubElement(a, '{%s}c' % ns)
2781 self.assertEqual('{%s}a' % ns,
2782 a.tag)
2783 self.assertEqual('{%s}b' % ns2,
2784 b.tag)
2785 self.assertEqual('{%s}c' % ns,
2786 c.tag)
2787 self.assertEqual('{%s}a' % ns,
2788 a.tag)
2789 self.assertEqual('{%s}b' % ns2,
2790 b.tag)
2791 self.assertEqual('{%s}c' % ns,
2792 c.tag)
2793
2795 Element = self.etree.Element
2796 SubElement = self.etree.SubElement
2797 ElementTree = self.etree.ElementTree
2798
2799 ns = 'http://xml.infrae.com/1'
2800 ns2 = 'http://xml.infrae.com/2'
2801 f = BytesIO('<a xmlns="%s" xmlns:x="%s"><x:b></x:b><b></b></a>' % (ns, ns2))
2802 t = ElementTree(file=f)
2803
2804 a = t.getroot()
2805 self.assertEqual('{%s}a' % ns,
2806 a.tag)
2807 self.assertEqual('{%s}b' % ns2,
2808 a[0].tag)
2809 self.assertEqual('{%s}b' % ns,
2810 a[1].tag)
2811
2813 Element = self.etree.Element
2814 ns = 'http://xml.infrae.com/1'
2815 ns2 = 'http://xml.infrae.com/2'
2816 a = Element('a')
2817 a.set('{%s}foo' % ns, 'Foo')
2818 a.set('{%s}bar' % ns2, 'Bar')
2819 self.assertEqual(
2820 'Foo',
2821 a.get('{%s}foo' % ns))
2822 self.assertEqual(
2823 'Bar',
2824 a.get('{%s}bar' % ns2))
2825 try:
2826 self.assertXML(
2827 _bytes('<a xmlns:ns0="%s" xmlns:ns1="%s" ns0:foo="Foo" ns1:bar="Bar"></a>' % (ns, ns2)),
2828 a)
2829 except AssertionError:
2830 self.assertXML(
2831 _bytes('<a xmlns:ns0="%s" xmlns:ns1="%s" ns1:foo="Foo" ns0:bar="Bar"></a>' % (ns2, ns)),
2832 a)
2833
2835 Element = self.etree.Element
2836 one = self.etree.fromstring(
2837 _bytes('<foo><bar xmlns:ns="http://a.b.c"><ns:baz/></bar></foo>'))
2838 baz = one[0][0]
2839
2840 two = Element('root')
2841 two.append(baz)
2842 # removing the originating document could cause a crash/error before
2843 # as namespace is not moved along with it
2844 del one, baz
2845 self.assertEqual('{http://a.b.c}baz', two[0].tag)
2846
2848 tostring = self.etree.tostring
2849 root = self.etree.XML(
2850 _bytes('<foo><bar xmlns:ns="http://a.b.c"><ns:baz/></bar></foo>'))
2851 baz = root[0][0]
2852
2853 nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
2854 tostring(baz))
2855 self.assertEqual([_bytes("http://a.b.c")], nsdecl)
2856
2858 tostring = self.etree.tostring
2859 root = self.etree.XML(
2860 _bytes('<foo><bar xmlns="http://a.b.c"><baz/></bar></foo>'))
2861 baz = root[0][0]
2862
2863 nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
2864 tostring(baz))
2865 self.assertEqual([_bytes("http://a.b.c")], nsdecl)
2866
2868 tostring = self.etree.tostring
2869 root = self.etree.XML(
2870 _bytes('<foo xmlns:ns="http://a.b.c"><bar><ns:baz/></bar></foo>'))
2871 baz = root[0][0]
2872
2873 nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
2874 tostring(baz))
2875
2876 self.assertEqual([_bytes("http://a.b.c")], nsdecl)
2877
2879 Element = self.etree.Element
2880 SubElement = self.etree.SubElement
2881
2882 root = Element("foo")
2883 bar = SubElement(root, "{http://a.b.c}bar")
2884 baz = SubElement(bar, "{http://a.b.c}baz")
2885
2886 nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
2887 self.etree.tostring(baz))
2888
2889 self.assertEqual([_bytes("http://a.b.c")], nsdecl)
2890
2892 Element = self.etree.Element
2893
2894 root = Element('element')
2895
2896 subelement = Element('subelement',
2897 {"{http://www.w3.org/XML/1998/namespace}id": "foo"})
2898 self.assertEqual(1, len(subelement.attrib))
2899 self.assertEqual(
2900 "foo",
2901 subelement.get("{http://www.w3.org/XML/1998/namespace}id"))
2902
2903 root.append(subelement)
2904 self.assertEqual(1, len(subelement.attrib))
2905 self.assertEqual(
2906 list({"{http://www.w3.org/XML/1998/namespace}id" : "foo"}.items()),
2907 list(subelement.attrib.items()))
2908 self.assertEqual(
2909 "foo",
2910 subelement.get("{http://www.w3.org/XML/1998/namespace}id"))
2911
2913 parse = self.etree.parse
2914 tostring = self.etree.tostring
2915
2916 ns_href = "http://a.b.c"
2917 one = parse(
2918 BytesIO('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2919 baz = one.getroot()[0][0]
2920
2921 parsed = parse(BytesIO( tostring(baz) )).getroot()
2922 self.assertEqual('{%s}baz' % ns_href, parsed.tag)
2923
2925 fromstring = self.etree.fromstring
2926 tostring = self.etree.tostring
2927
2928 ns_href = "http://a.b.c"
2929 xml = _bytes('<root xmlns="%s" xmlns:x="%s"><el x:a="test" /></root>' % (
2930 ns_href,ns_href))
2931 root = fromstring(xml)
2932 self.assertEqual('test', root[0].get('{%s}a' % ns_href))
2933
2934 xml2 = tostring(root)
2935 self.assertTrue(_bytes(':a=') in xml2, xml2)
2936
2937 root2 = fromstring(xml2)
2938 self.assertEqual('test', root2[0].get('{%s}a' % ns_href))
2939
2941 fromstring = self.etree.fromstring
2942 tostring = self.etree.tostring
2943
2944 ns_href = "http://a.b.c"
2945 xml = _bytes('<root xmlns="%s" xmlns:x="%s"><el x:a="test" /></root>' % (
2946 ns_href,ns_href))
2947 root = fromstring(xml)
2948 self.assertEqual('test', root[0].get('{%s}a' % ns_href))
2949
2950 root[0].set('{%s}a' % ns_href, 'TEST')
2951
2952 xml2 = tostring(root)
2953 self.assertTrue(_bytes(':a=') in xml2, xml2)
2954
2955 root2 = fromstring(xml2)
2956 self.assertEqual('TEST', root2[0].get('{%s}a' % ns_href))
2957
2958 required_versions_ET['test_register_namespace'] = (1,3)
2960 # ET 1.3+
2961 Element = self.etree.Element
2962 prefix = 'TESTPREFIX'
2963 namespace = 'http://seriously.unknown/namespace/URI'
2964
2965 el = Element('{%s}test' % namespace)
2966 self.assertEqual(_bytes('<ns0:test xmlns:ns0="%s"></ns0:test>' % namespace),
2967 self._writeElement(el))
2968
2969 self.etree.register_namespace(prefix, namespace)
2970 el = Element('{%s}test' % namespace)
2971 self.assertEqual(_bytes('<%s:test xmlns:%s="%s"></%s:test>' % (
2972 prefix, prefix, namespace, prefix)),
2973 self._writeElement(el))
2974
2975 self.assertRaises(ValueError, self.etree.register_namespace, 'ns25', namespace)
2976
2978 tostring = self.etree.tostring
2979 Element = self.etree.Element
2980 SubElement = self.etree.SubElement
2981
2982 a = Element('a')
2983 b = SubElement(a, 'b')
2984 c = SubElement(a, 'c')
2985
2986 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
2987 canonicalize(tostring(a)))
2988
2990 tostring = self.etree.tostring
2991 Element = self.etree.Element
2992 SubElement = self.etree.SubElement
2993
2994 a = Element('a')
2995 b = SubElement(a, 'b')
2996 c = SubElement(a, 'c')
2997 d = SubElement(c, 'd')
2998 self.assertEqual(_bytes('<b></b>'),
2999 canonicalize(tostring(b)))
3000 self.assertEqual(_bytes('<c><d></d></c>'),
3001 canonicalize(tostring(c)))
3002
3004 tostring = self.etree.tostring
3005 Element = self.etree.Element
3006 SubElement = self.etree.SubElement
3007
3008 a = Element('a')
3009 b = SubElement(a, 'b')
3010 c = SubElement(a, 'c')
3011 d = SubElement(c, 'd')
3012 b.tail = 'Foo'
3013
3014 self.assertTrue(tostring(b) == _bytes('<b/>Foo') or
3015 tostring(b) == _bytes('<b />Foo'))
3016
3017 required_versions_ET['test_tostring_method_html'] = (1,3)
3019 tostring = self.etree.tostring
3020 Element = self.etree.Element
3021 SubElement = self.etree.SubElement
3022
3023 html = Element('html')
3024 body = SubElement(html, 'body')
3025 p = SubElement(body, 'p')
3026 p.text = "html"
3027 SubElement(p, 'br').tail = "test"
3028
3029 self.assertEqual(_bytes('<html><body><p>html<br>test</p></body></html>'),
3030 tostring(html, method="html"))
3031
3032 required_versions_ET['test_tostring_method_text'] = (1,3)
3034 tostring = self.etree.tostring
3035 Element = self.etree.Element
3036 SubElement = self.etree.SubElement
3037
3038 a = Element('a')
3039 a.text = "A"
3040 a.tail = "tail"
3041 b = SubElement(a, 'b')
3042 b.text = "B"
3043 b.tail = "TAIL"
3044 c = SubElement(a, 'c')
3045 c.text = "C"
3046
3047 self.assertEqual(_bytes('ABTAILCtail'),
3048 tostring(a, method="text"))
3049
3051 iterparse = self.etree.iterparse
3052 f = BytesIO('<a><b></b><c/></a>')
3053
3054 iterator = iterparse(f)
3055 self.assertEqual(None,
3056 iterator.root)
3057 events = list(iterator)
3058 root = iterator.root
3059 self.assertEqual(
3060 [('end', root[0]), ('end', root[1]), ('end', root)],
3061 events)
3062
3064 iterparse = self.etree.iterparse
3065 f = BytesIO('<a><b></b><c/></a>')
3066
3067 iterator = iterparse(f)
3068 self.assertEqual(None,
3069 iterator.root)
3070 event, element = next(iter(iterator))
3071 self.assertEqual('end', event)
3072 self.assertEqual('b', element.tag)
3073
3075 iterparse = self.etree.iterparse
3076 iterator = iterparse(fileInTestDir("test.xml"))
3077 self.assertEqual(None,
3078 iterator.root)
3079 events = list(iterator)
3080 root = iterator.root
3081 self.assertEqual(
3082 [('end', root[0]), ('end', root)],
3083 events)
3084
3086 iterparse = self.etree.iterparse
3087 f = BytesIO('<a><b></b><c/></a>')
3088
3089 iterator = iterparse(f, events=('start',))
3090 events = list(iterator)
3091 root = iterator.root
3092 self.assertEqual(
3093 [('start', root), ('start', root[0]), ('start', root[1])],
3094 events)
3095
3097 iterparse = self.etree.iterparse
3098 f = BytesIO('<a><b></b><c/></a>')
3099
3100 iterator = iterparse(f, events=('start','end'))
3101 events = list(iterator)
3102 root = iterator.root
3103 self.assertEqual(
3104 [('start', root), ('start', root[0]), ('end', root[0]),
3105 ('start', root[1]), ('end', root[1]), ('end', root)],
3106 events)
3107
3109 iterparse = self.etree.iterparse
3110 f = BytesIO('<a><b></b><c/></a>')
3111
3112 iterator = iterparse(f)
3113 for event, elem in iterator:
3114 elem.clear()
3115
3116 root = iterator.root
3117 self.assertEqual(0,
3118 len(root))
3119
3121 iterparse = self.etree.iterparse
3122 CHILD_COUNT = 12345
3123 f = BytesIO('<a>%s</a>' % ('<b>test</b>'*CHILD_COUNT))
3124
3125 i = 0
3126 for key in iterparse(f):
3127 event, element = key
3128 i += 1
3129 self.assertEqual(i, CHILD_COUNT + 1)
3130
3132 iterparse = self.etree.iterparse
3133 f = BytesIO('<a xmlns="http://ns1/"><b><c xmlns="http://ns2/"/></b></a>')
3134
3135 attr_name = '{http://testns/}bla'
3136 events = []
3137 iterator = iterparse(f, events=('start','end','start-ns','end-ns'))
3138 for event, elem in iterator:
3139 events.append(event)
3140 if event == 'start':
3141 if elem.tag != '{http://ns1/}a':
3142 elem.set(attr_name, 'value')
3143
3144 self.assertEqual(
3145 ['start-ns', 'start', 'start', 'start-ns', 'start',
3146 'end', 'end-ns', 'end', 'end', 'end-ns'],
3147 events)
3148
3149 root = iterator.root
3150 self.assertEqual(
3151 None,
3152 root.get(attr_name))
3153 self.assertEqual(
3154 'value',
3155 root[0].get(attr_name))
3156
3158 iterparse = self.etree.iterparse
3159 f = BytesIO('<a xmlns="http://ns1/"><b><c xmlns="http://ns2/"/></b></a>')
3160
3161 attr_name = '{http://testns/}bla'
3162 events = []
3163 iterator = iterparse(f, events=('start','end','start-ns','end-ns'))
3164 for event, elem in iterator:
3165 events.append(event)
3166 if event == 'start':
3167 if elem.tag != '{http://ns1/}a':
3168 elem.set(attr_name, 'value')
3169
3170 self.assertEqual(
3171 ['start-ns', 'start', 'start', 'start-ns', 'start',
3172 'end', 'end-ns', 'end', 'end', 'end-ns'],
3173 events)
3174
3175 root = iterator.root
3176 self.assertEqual(
3177 None,
3178 root.get(attr_name))
3179 self.assertEqual(
3180 'value',
3181 root[0].get(attr_name))
3182
3184 iterparse = self.etree.iterparse
3185 f = BytesIO('<a><b><d/></b><c/></a>')
3186
3187 counts = []
3188 for event, elem in iterparse(f):
3189 counts.append(len(list(elem.getiterator())))
3190 self.assertEqual(
3191 [1,2,1,4],
3192 counts)
3193
3195 iterparse = self.etree.iterparse
3196 f = BytesIO('<a><b><d/></b><c/></a>')
3197
3198 for event, node in etree.iterparse(f): pass
3199
3200 root = etree.Element('new_root', {})
3201 root[:] = node[:]
3202
3203 self.assertEqual(
3204 ['b', 'c'],
3205 [ el.tag for el in root ])
3206
3208 tostring = self.etree.tostring
3209 f = BytesIO('<root><![CDATA[test]]></root>')
3210 context = self.etree.iterparse(f)
3211 content = [ el.text for event,el in context ]
3212
3213 self.assertEqual(['test'], content)
3214 self.assertEqual(_bytes('<root>test</root>'),
3215 tostring(context.root))
3216
3218 parse = self.etree.parse
3219 # from file
3220 tree = parse(fileInTestDir('test.xml'))
3221 self.assertXML(
3222 _bytes('<a><b></b></a>'),
3223 tree.getroot())
3224
3228
3232
3233 required_versions_ET['test_parse_error'] = (1,3)
3235 # ET < 1.3 raises ExpatError
3236 parse = self.etree.parse
3237 f = BytesIO('<a><b></c></b></a>')
3238 self.assertRaises(SyntaxError, parse, f)
3239 f.close()
3240
3241 required_versions_ET['test_parse_error_from_file'] = (1,3)
3243 parse = self.etree.parse
3244 # from file
3245 f = open(fileInTestDir('test_broken.xml'), 'rb')
3246 self.assertRaises(SyntaxError, parse, f)
3247 f.close()
3248
3250 parse = self.etree.parse
3251 # from file object
3252 f = open(fileInTestDir('test.xml'), 'rb')
3253 tree = parse(f)
3254 f.close()
3255 self.assertXML(
3256 _bytes('<a><b></b></a>'),
3257 tree.getroot())
3258
3260 parse = self.etree.parse
3261 f = BytesIO('<a><b></b></a>')
3262 tree = parse(f)
3263 f.close()
3264 self.assertXML(
3265 _bytes('<a><b></b></a>'),
3266 tree.getroot()
3267 )
3268
3270 tostring = self.etree.tostring
3271 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'))
3272
3273 self.assertEqual('test', root.text)
3274 self.assertEqual(_bytes('<root>test</root>'),
3275 tostring(root))
3276
3278 # this can fail in libxml2 <= 2.6.22
3279 parse = self.etree.parse
3280 tree = parse(BytesIO('<?xml version="1.0" encoding="ascii"?><html/>'))
3281 self.assertXML(_bytes('<html></html>'),
3282 tree.getroot())
3283
3285 Element = self.etree.Element
3286
3287 a = Element('a')
3288 a.text = _str('Søk på nettet')
3289 self.assertXML(
3290 _str('<a>Søk på nettet</a>').encode('UTF-8'),
3291 a, 'utf-8')
3292
3294 ElementTree = self.etree.ElementTree
3295 Element = self.etree.Element
3296
3297 a = Element('a')
3298 a.text = _str('Søk på nettet')
3299
3300 f = BytesIO()
3301 tree = ElementTree(element=a)
3302 tree.write(f, encoding='utf-8')
3303 self.assertEqual(_str('<a>Søk på nettet</a>').encode('UTF-8'),
3304 f.getvalue().replace(_bytes('\n'),_bytes('')))
3305
3307 parse = self.etree.parse
3308 # from file
3309 tree = parse(fileInTestDir('test-string.xml'))
3310 self.assertXML(
3311 _str('<a>Søk på nettet</a>').encode('UTF-8'),
3312 tree.getroot(), 'UTF-8')
3313
3315 parse = self.etree.parse
3316 # from file object
3317 f = open(fileInTestDir('test-string.xml'), 'rb')
3318 tree = parse(f)
3319 f.close()
3320 self.assertXML(
3321 _str('<a>Søk på nettet</a>').encode('UTF-8'),
3322 tree.getroot(), 'UTF-8')
3323
3325 ElementTree = self.etree.ElementTree
3326 Element = self.etree.Element
3327
3328 a = Element('a')
3329 a.text = _str('Søk på nettet')
3330
3331 f = BytesIO()
3332 tree = ElementTree(element=a)
3333 tree.write(f, encoding='iso-8859-1')
3334 result = f.getvalue()
3335 declaration = _bytes("<?xml version=\'1.0\' encoding=\'iso-8859-1\'?>")
3336 self.assertEncodingDeclaration(result, _bytes('iso-8859-1'))
3337 result = result.split(_bytes('?>'), 1)[-1].replace(_bytes('\n'),_bytes(''))
3338 self.assertEqual(_str('<a>Søk på nettet</a>').encode('iso-8859-1'),
3339 result)
3340
3341 required_versions_ET['test_parse_encoding_8bit_explicit'] = (1,3)
3343 XMLParser = self.XMLParser
3344
3345 text = _str('Søk på nettet')
3346 xml_latin1 = (_str('<a>%s</a>') % text).encode('iso-8859-1')
3347
3348 self.assertRaises(self.etree.ParseError,
3349 self.etree.parse,
3350 BytesIO(xml_latin1))
3351
3352 tree = self.etree.parse(BytesIO(xml_latin1),
3353 XMLParser(encoding="iso-8859-1"))
3354 a = tree.getroot()
3355 self.assertEqual(a.text, text)
3356
3357 required_versions_ET['test_parse_encoding_8bit_override'] = (1,3)
3359 XMLParser = self.XMLParser
3360
3361 text = _str('Søk på nettet')
3362 wrong_declaration = _str("<?xml version='1.0' encoding='UTF-8'?>")
3363 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
3364 ).encode('iso-8859-1')
3365
3366 self.assertRaises(self.etree.ParseError,
3367 self.etree.parse,
3368 BytesIO(xml_latin1))
3369
3370 tree = self.etree.parse(BytesIO(xml_latin1),
3371 XMLParser(encoding="iso-8859-1"))
3372 a = tree.getroot()
3373 self.assertEqual(a.text, text)
3374
3376 # raise error on wrong encoding declaration in unicode strings
3377 XML = self.etree.XML
3378 test_utf = (_str('<?xml version="1.0" encoding="iso-8859-1"?>') +
3379 _str('<a>Søk på nettet</a>'))
3380 self.assertRaises(SyntaxError, XML, test_utf)
3381
3383 ElementTree = self.etree.ElementTree
3384 Element = self.etree.Element
3385
3386 a = Element('a')
3387 a.text = _str('Søk på nettet')
3388
3389 f = BytesIO()
3390 tree = ElementTree(element=a)
3391 tree.write(f)
3392 data = f.getvalue().replace(_bytes('\n'),_bytes(''))
3393 self.assertEqual(
3394 _str('<a>Søk på nettet</a>').encode('ASCII', 'xmlcharrefreplace'),
3395 data)
3396
3398 Element = self.etree.Element
3399 tostring = self.etree.tostring
3400
3401 a = Element('a')
3402 a.text = _str('Søk på nettet')
3403 self.assertEqual(_str('<a>Søk på nettet</a>').encode('UTF-8'),
3404 tostring(a, encoding='utf-8'))
3405
3407 Element = self.etree.Element
3408 tostring = self.etree.tostring
3409
3410 a = Element('a')
3411 a.text = _str('Søk på nettet')
3412 self.assertRaises(LookupError, tostring, a,
3413 encoding='Invalid Encoding')
3414
3416 Element = self.etree.Element
3417 SubElement = self.etree.SubElement
3418 tostring = self.etree.tostring
3419
3420 a = Element('a')
3421 b = SubElement(a, 'b')
3422 b.text = _str('Søk på nettet')
3423 self.assertEqual(_str('<b>Søk på nettet</b>').encode('UTF-8'),
3424 tostring(b, encoding='utf-8'))
3425
3427 Element = self.etree.Element
3428 SubElement = self.etree.SubElement
3429 tostring = self.etree.tostring
3430
3431 a = Element('a')
3432 b = SubElement(a, 'b')
3433 b.text = _str('Søk på nettet')
3434 b.tail = _str('Søk')
3435 self.assertEqual(_str('<b>Søk på nettet</b>Søk').encode('UTF-8'),
3436 tostring(b, encoding='utf-8'))
3437
3439 Element = self.etree.Element
3440 SubElement = self.etree.SubElement
3441 tostring = self.etree.tostring
3442
3443 a = Element('a')
3444 a.text = _str('Søk på nettet')
3445
3446 expected = _bytes('<a>Søk på nettet</a>')
3447 self.assertEqual(
3448 expected,
3449 tostring(a))
3450
3452 Element = self.etree.Element
3453 SubElement = self.etree.SubElement
3454 tostring = self.etree.tostring
3455
3456 a = Element('a')
3457 b = SubElement(a, 'b')
3458 b.text = _str('Søk på nettet')
3459
3460 expected = _bytes('<b>Søk på nettet</b>')
3461 self.assertEqual(
3462 expected,
3463 tostring(b))
3464
3466 utext = _str('Søk på nettet')
3467 uxml = _str('<p>%s</p>') % utext
3468 prologue = _bytes('<?xml version="1.0" encoding="iso-8859-1" ?>')
3469 isoxml = prologue + uxml.encode('iso-8859-1')
3470 tree = self.etree.XML(isoxml)
3471 self.assertEqual(utext, tree.text)
3472
3474 utext = _str('Søk på nettet')
3475 uxml = (_str('<?xml version="1.0" encoding="UTF-8"?>') +
3476 _str('<p>%s</p>') % utext)
3477 bom = _bytes('\\xEF\\xBB\\xBF').decode("unicode_escape").encode("latin1")
3478 xml = bom + uxml.encode("utf-8")
3479 tree = etree.XML(xml)
3480 self.assertEqual(utext, tree.text)
3481
3483 utext = _str('Søk på nettet')
3484 uxml = _str('<p>%s</p>') % utext
3485 prologue = _bytes('<?xml version="1.0" encoding="iso-8859-1" ?>')
3486 isoxml = prologue + uxml.encode('iso-8859-1')
3487 el = self.etree.parse(BytesIO(isoxml)).getroot()
3488 self.assertEqual(utext, el.text)
3489
3491 Element = self.etree.Element
3492 ElementTree = self.etree.ElementTree
3493
3494 a = Element('a')
3495 a.text = "Foo"
3496 atree = ElementTree(a)
3497
3498 btree = copy.deepcopy(atree)
3499 self.assertEqual("Foo", atree.getroot().text)
3500 self.assertEqual("Foo", btree.getroot().text)
3501 self.assertFalse(btree is atree)
3502 self.assertFalse(btree.getroot() is atree.getroot())
3503
3505 Element = self.etree.Element
3506
3507 a = Element('a')
3508 a.text = 'Foo'
3509
3510 b = copy.deepcopy(a)
3511 self.assertEqual('Foo', b.text)
3512
3513 b.text = 'Bar'
3514 self.assertEqual('Bar', b.text)
3515 self.assertEqual('Foo', a.text)
3516
3517 del a
3518 self.assertEqual('Bar', b.text)
3519
3521 Element = self.etree.Element
3522
3523 a = Element('a')
3524 a.tail = 'Foo'
3525
3526 b = copy.deepcopy(a)
3527 self.assertEqual('Foo', b.tail)
3528
3529 b.tail = 'Bar'
3530 self.assertEqual('Bar', b.tail)
3531 self.assertEqual('Foo', a.tail)
3532
3533 del a
3534 self.assertEqual('Bar', b.tail)
3535
3537 Element = self.etree.Element
3538 SubElement = self.etree.SubElement
3539
3540 root = Element('root')
3541 a = SubElement(root, 'a')
3542 a.text = 'FooText'
3543 a.tail = 'FooTail'
3544
3545 b = copy.deepcopy(a)
3546 self.assertEqual('FooText', b.text)
3547 self.assertEqual('FooTail', b.tail)
3548
3549 b.text = 'BarText'
3550 b.tail = 'BarTail'
3551 self.assertEqual('BarTail', b.tail)
3552 self.assertEqual('FooTail', a.tail)
3553 self.assertEqual('BarText', b.text)
3554 self.assertEqual('FooText', a.text)
3555
3556 del a
3557 self.assertEqual('BarTail', b.tail)
3558 self.assertEqual('BarText', b.text)
3559
3561 root = self.etree.XML(_bytes('''<doc xmlns="dns" xmlns:t="tns">
3562 <parent><node t:foo="bar" /></parent>
3563 </doc>'''))
3564 self.assertEqual(
3565 root[0][0].get('{tns}foo'),
3566 copy.deepcopy(root[0])[0].get('{tns}foo') )
3567 self.assertEqual(
3568 root[0][0].get('{tns}foo'),
3569 copy.deepcopy(root[0][0]).get('{tns}foo') )
3570
3572 # previously caused a crash
3573 Element = self.etree.Element
3574 tostring = self.etree.tostring
3575
3576 a = Element('a')
3577 b = copy.deepcopy(a)
3578 a.append( Element('C') )
3579 b.append( Element('X') )
3580
3581 self.assertEqual(_bytes('<a><C/></a>'),
3582 tostring(a).replace(_bytes(' '), _bytes('')))
3583 self.assertEqual(_bytes('<a><X/></a>'),
3584 tostring(b).replace(_bytes(' '), _bytes('')))
3585
3587 # previously caused a crash
3588 # not supported by ET < 1.3!
3589 Comment = self.etree.Comment
3590
3591 a = Comment("ONE")
3592 b = copy.deepcopy(a)
3593 b.text = "ANOTHER"
3594
3595 self.assertEqual('ONE', a.text)
3596 self.assertEqual('ANOTHER', b.text)
3597
3599 Element = self.etree.Element
3600
3601 a = Element('a')
3602 a.text = 'Foo'
3603
3604 b = copy.copy(a)
3605 self.assertEqual('Foo', b.text)
3606
3607 b.text = 'Bar'
3608 self.assertEqual('Bar', b.text)
3609 self.assertEqual('Foo', a.text)
3610 # XXX ElementTree will share nodes, but lxml.etree won't..
3611
3613 Element = self.etree.Element
3614 ElementTree = self.etree.ElementTree
3615
3616 a = Element('a')
3617 a.text = 'Foo'
3618 atree = ElementTree(a)
3619
3620 btree = copy.copy(atree)
3621 self.assertFalse(btree is atree)
3622 self.assertTrue(btree.getroot() is atree.getroot())
3623 self.assertEqual('Foo', atree.getroot().text)
3624
3626 # deprecated as of ET 1.3/lxml 2.0
3627 etree = self.etree
3628 e = etree.Element('foo')
3629 self.assertEqual(False, bool(e))
3630 etree.SubElement(e, 'bar')
3631 self.assertEqual(True, bool(e))
3632 e = etree.Element('foo')
3633 e.text = 'hey'
3634 self.assertEqual(False, bool(e))
3635 e = etree.Element('foo')
3636 e.tail = 'bar'
3637 self.assertEqual(False, bool(e))
3638 e = etree.Element('foo')
3639 e.set('bar', 'Bar')
3640 self.assertEqual(False, bool(e))
3641
3643 etree = self.etree
3644
3645 a = etree.Element('a')
3646 b = etree.SubElement(a, 'b')
3647
3648 t = etree.ElementTree(a)
3649 self.assertEqual(self._rootstring(t), _bytes('<a><b/></a>'))
3650
3651 t1 = etree.ElementTree(a)
3652 self.assertEqual(self._rootstring(t1), _bytes('<a><b/></a>'))
3653 self.assertEqual(self._rootstring(t), _bytes('<a><b/></a>'))
3654
3655 t2 = etree.ElementTree(b)
3656 self.assertEqual(self._rootstring(t2), _bytes('<b/>'))
3657 self.assertEqual(self._rootstring(t1), _bytes('<a><b/></a>'))
3658 self.assertEqual(self._rootstring(t), _bytes('<a><b/></a>'))
3659
3661 etree = self.etree
3662 qname = etree.QName('myns', 'a')
3663 a1 = etree.Element(qname)
3664 a2 = etree.SubElement(a1, qname)
3665 self.assertEqual(a1.tag, "{myns}a")
3666 self.assertEqual(a2.tag, "{myns}a")
3667
3669 etree = self.etree
3670 qname1 = etree.QName('myns', 'a')
3671 qname2 = etree.QName('myns', 'a')
3672 self.assertEqual(qname1, "{myns}a")
3673 self.assertEqual("{myns}a", qname2)
3674 self.assertEqual(qname1, qname1)
3675 self.assertEqual(qname1, qname2)
3676
3678 etree = self.etree
3679 qname = etree.QName('myns', 'a')
3680
3681 a = etree.Element(qname)
3682 a.set(qname, "value")
3683
3684 self.assertEqual(a.get(qname), "value")
3685 self.assertEqual(a.get("{myns}a"), "value")
3686
3688 etree = self.etree
3689 qname = etree.QName('myns', 'a')
3690
3691 a = etree.Element(qname)
3692 a.attrib[qname] = "value"
3693
3694 self.assertEqual(a.attrib[qname], "value")
3695 self.assertEqual(a.attrib.get(qname), "value")
3696
3697 self.assertEqual(a.attrib["{myns}a"], "value")
3698 self.assertEqual(a.attrib.get("{myns}a"), "value")
3699
3701 etree = self.etree
3702 qname = etree.QName('http://myns', 'a')
3703 a = etree.Element(qname)
3704 a.set(qname, qname)
3705
3706 self.assertXML(
3707 _bytes('<ns0:a xmlns:ns0="http://myns" ns0:a="ns0:a"></ns0:a>'),
3708 a)
3709
3711 etree = self.etree
3712 qname = etree.QName('http://myns', 'a')
3713 a = etree.Element('a')
3714 a.set('a', qname)
3715
3716 self.assertXML(
3717 _bytes('<a xmlns:ns0="http://myns" a="ns0:a"></a>'),
3718 a)
3719
3721 etree = self.etree
3722 qname = etree.QName('http://myns', 'a')
3723 a = etree.Element(qname)
3724 a.attrib[qname] = qname
3725
3726 self.assertXML(
3727 _bytes('<ns0:a xmlns:ns0="http://myns" ns0:a="ns0:a"></ns0:a>'),
3728 a)
3729
3731 etree = self.etree
3732 parser = etree.XMLParser()
3733 if hasattr(parser, "version"):
3734 # ElementTree 1.3+, cET
3735 self.assertTrue(re.match("[^ ]+ [0-9.]+", parser.version))
3736
3737 # feed parser interface
3738
3740 parser = self.XMLParser()
3741
3742 parser.feed(_bytes('<?xml version='))
3743 parser.feed(_bytes('"1.0"?><ro'))
3744 parser.feed(_bytes('ot><'))
3745 parser.feed(_bytes('a test="works"/'))
3746 parser.feed(_bytes('></root'))
3747 parser.feed(_bytes('>'))
3748
3749 root = parser.close()
3750
3751 self.assertEqual(root.tag, "root")
3752 self.assertEqual(root[0].tag, "a")
3753 self.assertEqual(root[0].get("test"), "works")
3754
3756 parser = self.XMLParser()
3757
3758 parser.feed(_str('<ro'))
3759 parser.feed(_str('ot><'))
3760 parser.feed(_str('a test="works"/'))
3761 parser.feed(_str('></root'))
3762 parser.feed(_str('>'))
3763
3764 root = parser.close()
3765
3766 self.assertEqual(root.tag, "root")
3767 self.assertEqual(root[0].tag, "a")
3768 self.assertEqual(root[0].get("test"), "works")
3769
3770 required_versions_ET['test_feed_parser_error_close_empty'] = (1,3)
3772 ParseError = self.etree.ParseError
3773 parser = self.XMLParser()
3774 self.assertRaises(ParseError, parser.close)
3775
3776 required_versions_ET['test_feed_parser_error_close_incomplete'] = (1,3)
3778 ParseError = self.etree.ParseError
3779 parser = self.XMLParser()
3780
3781 parser.feed('<?xml version=')
3782 parser.feed('"1.0"?><ro')
3783
3784 self.assertRaises(ParseError, parser.close)
3785
3786 required_versions_ET['test_feed_parser_error_broken'] = (1,3)
3788 ParseError = self.etree.ParseError
3789 parser = self.XMLParser()
3790
3791 parser.feed('<?xml version=')
3792 parser.feed('"1.0"?><ro')
3793 try:
3794 parser.feed('<><><><><><><')
3795 except ParseError:
3796 # can raise, but not required before close()
3797 pass
3798
3799 self.assertRaises(ParseError, parser.close)
3800
3801 required_versions_ET['test_feed_parser_error_position'] = (1,3)
3803 ParseError = self.etree.ParseError
3804 parser = self.XMLParser()
3805 try:
3806 parser.close()
3807 except ParseError:
3808 e = sys.exc_info()[1]
3809 self.assertNotEqual(None, e.code)
3810 self.assertNotEqual(0, e.code)
3811 self.assertTrue(isinstance(e.position, tuple))
3812 self.assertTrue(e.position >= (0, 0))
3813
3814 # parser target interface
3815
3816 required_versions_ET['test_parser_target_property'] = (1,3)
3820
3821 target = Target()
3822 parser = self.XMLParser(target=target)
3823
3824 self.assertEqual(target, parser.target)
3825
3827 assertEqual = self.assertEqual
3828 assertFalse = self.assertFalse
3829
3830 events = []
3831 class Target(object):
3832 def start(self, tag, attrib):
3833 events.append("start")
3834 assertFalse(attrib)
3835 assertEqual("TAG", tag)
3836 def end(self, tag):
3837 events.append("end")
3838 assertEqual("TAG", tag)
3839 def close(self):
3840 return "DONE"
3841
3842 parser = self.XMLParser(target=Target())
3843
3844 parser.feed("<TAG/>")
3845 done = parser.close()
3846
3847 self.assertEqual("DONE", done)
3848 self.assertEqual(["start", "end"], events)
3849
3851 assertEqual = self.assertEqual
3852
3853 events = []
3854 class Target(object):
3855 def start(self, tag, attrib):
3856 events.append("start")
3857 assertEqual("TAG", tag)
3858 raise ValueError("TEST")
3859 def end(self, tag):
3860 events.append("end")
3861 assertEqual("TAG", tag)
3862 def close(self):
3863 return "DONE"
3864
3865 parser = self.XMLParser(target=Target())
3866
3867 try:
3868 parser.feed("<TAG/>")
3869 except ValueError:
3870 self.assertTrue('TEST' in str(sys.exc_info()[1]))
3871 else:
3872 self.assertTrue(False)
3873 if 'lxml' in self.etree.__name__:
3874 self.assertEqual(["start"], events)
3875 else:
3876 # cElementTree calls end() as well
3877 self.assertTrue("start" in events)
3878
3880 assertEqual = self.assertEqual
3881
3882 events = []
3883 class Target(object):
3884 def start(self, tag, attrib):
3885 events.append("start")
3886 assertEqual("TAG", tag)
3887 def end(self, tag):
3888 events.append("end")
3889 assertEqual("TAG", tag)
3890 raise ValueError("TEST")
3891 def close(self):
3892 return "DONE"
3893
3894 parser = self.XMLParser(target=Target())
3895
3896 try:
3897 parser.feed("<TAG/>")
3898 except ValueError:
3899 self.assertTrue('TEST' in str(sys.exc_info()[1]))
3900 else:
3901 self.assertTrue(False)
3902 self.assertEqual(["start", "end"], events)
3903
3905 assertEqual = self.assertEqual
3906
3907 events = []
3908 class Target(object):
3909 def start(self, tag, attrib):
3910 events.append("start")
3911 assertEqual("TAG", tag)
3912 def end(self, tag):
3913 events.append("end")
3914 assertEqual("TAG", tag)
3915 def close(self):
3916 raise ValueError("TEST")
3917
3918 parser = self.XMLParser(target=Target())
3919
3920 try:
3921 parser.feed("<TAG/>")
3922 parser.close()
3923 except ValueError:
3924 self.assertTrue('TEST' in str(sys.exc_info()[1]))
3925 else:
3926 self.assertTrue(False)
3927 self.assertEqual(["start", "end"], events)
3928
3930 assertEqual = self.assertEqual
3931
3932 events = []
3933 class Target(object):
3934 def start(self, tag, attrib):
3935 events.append("start")
3936 assertEqual("TAG", tag)
3937 raise IndexError("TEST-IE")
3938 def end(self, tag):
3939 events.append("end")
3940 assertEqual("TAG", tag)
3941 def close(self):
3942 raise ValueError("TEST-VE")
3943
3944 parser = self.XMLParser(target=Target())
3945
3946 try:
3947 parser.feed("<TAG/>")
3948 parser.close()
3949 except IndexError:
3950 if 'lxml' in self.etree.__name__:
3951 # we try not to swallow the initial exception in Py2
3952 self.assertTrue(sys.version_info[0] < 3)
3953 self.assertTrue('TEST-IE' in str(sys.exc_info()[1]))
3954 except ValueError:
3955 if 'lxml' in self.etree.__name__:
3956 self.assertTrue(sys.version_info[0] >= 3)
3957 self.assertTrue('TEST-VE' in str(sys.exc_info()[1]))
3958 else:
3959 self.assertTrue(False)
3960
3961 if 'lxml' in self.etree.__name__:
3962 self.assertEqual(["start"], events)
3963 else:
3964 # cElementTree calls end() as well
3965 self.assertTrue("start" in events)
3966
3968 assertEqual = self.assertEqual
3969 assertFalse = self.assertFalse
3970 Element = self.etree.Element
3971
3972 events = []
3973 class Target(object):
3974 def start(self, tag, attrib):
3975 events.append("start")
3976 assertFalse(attrib)
3977 assertEqual("TAG", tag)
3978 def end(self, tag):
3979 events.append("end")
3980 assertEqual("TAG", tag)
3981 def close(self):
3982 return Element("DONE")
3983
3984 parser = self.XMLParser(target=Target())
3985 tree = self.etree.ElementTree()
3986 tree.parse(BytesIO("<TAG/>"), parser=parser)
3987
3988 self.assertEqual("DONE", tree.getroot().tag)
3989 self.assertEqual(["start", "end"], events)
3990
3992 assertEqual = self.assertEqual
3993
3994 events = []
3995 class Target(object):
3996 def start(self, tag, attrib):
3997 events.append("start-" + tag)
3998 for name, value in attrib.items():
3999 assertEqual(tag + name, value)
4000 def end(self, tag):
4001 events.append("end-" + tag)
4002 def close(self):
4003 return "DONE"
4004
4005 parser = self.XMLParser(target=Target())
4006
4007 parser.feed('<root a="roota" b="rootb"><sub c="subc"/></root>')
4008 done = parser.close()
4009
4010 self.assertEqual("DONE", done)
4011 self.assertEqual(["start-root", "start-sub", "end-sub", "end-root"],
4012 events)
4013
4015 events = []
4016 class Target(object):
4017 def start(self, tag, attrib):
4018 events.append("start-" + tag)
4019 def end(self, tag):
4020 events.append("end-" + tag)
4021 def data(self, data):
4022 events.append("data-" + data)
4023 def close(self):
4024 return "DONE"
4025
4026 parser = self.XMLParser(target=Target())
4027
4028 parser.feed('<root>A<sub/>B</root>')
4029 done = parser.close()
4030
4031 self.assertEqual("DONE", done)
4032 self.assertEqual(["start-root", "data-A", "start-sub",
4033 "end-sub", "data-B", "end-root"],
4034 events)
4035
4041 def _flush_data(self):
4042 if self._data:
4043 events.append("data-" + ''.join(self._data))
4044 del self._data[:]
4045 def start(self, tag, attrib):
4046 self._flush_data()
4047 events.append("start-" + tag)
4048 def end(self, tag):
4049 self._flush_data()
4050 events.append("end-" + tag)
4051 def data(self, data):
4052 self._data.append(data)
4053 def close(self):
4054 self._flush_data()
4055 return "DONE"
4056
4057 parser = self.XMLParser(target=Target())
4058
4059 dtd = '''
4060 <!DOCTYPE root [
4061 <!ELEMENT root (sub*)>
4062 <!ELEMENT sub (#PCDATA)>
4063 <!ENTITY ent "an entity">
4064 ]>
4065 '''
4066 parser.feed(dtd+'<root><sub/><sub>this is &ent;</sub><sub/></root>')
4067 done = parser.close()
4068
4069 self.assertEqual("DONE", done)
4070 self.assertEqual(["start-root", "start-sub", "end-sub", "start-sub",
4071 "data-this is an entity",
4072 "end-sub", "start-sub", "end-sub", "end-root"],
4073 events)
4074
4075 required_versions_ET['test_parser_target_entity_unknown'] = (1,3)
4081 def _flush_data(self):
4082 if self._data:
4083 events.append("data-" + ''.join(self._data))
4084 del self._data[:]
4085 def start(self, tag, attrib):
4086 self._flush_data()
4087 events.append("start-" + tag)
4088 def end(self, tag):
4089 self._flush_data()
4090 events.append("end-" + tag)
4091 def data(self, data):
4092 self._data.append(data)
4093 def close(self):
4094 self._flush_data()
4095 return "DONE"
4096
4097 parser = self.XMLParser(target=Target())
4098
4099 def feed():
4100 parser.feed('<root><sub/><sub>some &ent;</sub><sub/></root>')
4101 parser.close()
4102
4103 self.assertRaises(self.etree.ParseError, feed)
4104
4105 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4110 def end(self, tag):
4111 self.append(("end", tag))
4112 def data(self, text):
4113 pass
4114 def pi(self, target, data):
4115 self.append(("pi", target, data))
4116 def comment(self, data):
4117 self.append(("comment", data))
4118 def start_ns(self, prefix, uri):
4119 self.append(("start-ns", prefix, uri))
4120 def end_ns(self, prefix):
4121 self.append(("end-ns", prefix))
4122
4123 builder = Builder()
4124 parser = self.etree.XMLParser(target=builder)
4125 parser.feed(textwrap.dedent("""\
4126 <?pi data?>
4127 <!-- comment -->
4128 <root xmlns='namespace'>
4129 <element key='value'>text</element>
4130 <element>text</element>tail
4131 <empty-element/>
4132 </root>
4133 """))
4134 self.assertEqual(builder, [
4135 ('pi', 'pi', 'data'),
4136 ('comment', ' comment '),
4137 ('start-ns', '', 'namespace'),
4138 ('start', '{namespace}root'),
4139 ('start', '{namespace}element'),
4140 ('end', '{namespace}element'),
4141 ('start', '{namespace}element'),
4142 ('end', '{namespace}element'),
4143 ('start', '{namespace}empty-element'),
4144 ('end', '{namespace}empty-element'),
4145 ('end', '{namespace}root'),
4146 ('end-ns', ''),
4147 ])
4148
4149 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4154
4155 builder = Builder()
4156 parser = self.etree.XMLParser(target=builder)
4157 parser.feed(textwrap.dedent("""\
4158 <?pi data?>
4159 <!-- comment -->
4160 <root xmlns='namespace' xmlns:p='pns'>
4161 <element key='value'>text</element>
4162 <p:element>text</p:element>tail
4163 <empty-element/>
4164 </root>
4165 """))
4166 self.assertEqual(builder, [
4167 ('end-ns', 'p'),
4168 ('end-ns', ''),
4169 ])
4170
4172 builder = self.etree.TreeBuilder()
4173 el = builder.start("root", {'a':'A', 'b':'B'})
4174 self.assertEqual("root", el.tag)
4175 self.assertEqual({'a':'A', 'b':'B'}, el.attrib)
4176 builder.data("ROOTTEXT")
4177 el = builder.start("child", {'x':'X', 'y':'Y'})
4178 self.assertEqual("child", el.tag)
4179 self.assertEqual({'x':'X', 'y':'Y'}, el.attrib)
4180 builder.data("CHILDTEXT")
4181 el = builder.end("child")
4182 self.assertEqual("child", el.tag)
4183 self.assertEqual({'x':'X', 'y':'Y'}, el.attrib)
4184 self.assertEqual("CHILDTEXT", el.text)
4185 self.assertEqual(None, el.tail)
4186 builder.data("CHILDTAIL")
4187 root = builder.end("root")
4188
4189 self.assertEqual("root", root.tag)
4190 self.assertEqual("ROOTTEXT", root.text)
4191 self.assertEqual("CHILDTEXT", root[0].text)
4192 self.assertEqual("CHILDTAIL", root[0].tail)
4193
4195 parser = self.XMLParser(target=self.etree.TreeBuilder())
4196 parser.feed('<root>ROOTTEXT<child>CHILDTEXT</child>CHILDTAIL</root>')
4197 root = parser.close()
4198
4199 self.assertEqual("root", root.tag)
4200 self.assertEqual("ROOTTEXT", root.text)
4201 self.assertEqual("CHILDTEXT", root[0].text)
4202 self.assertEqual("CHILDTAIL", root[0].tail)
4203
4204 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4206 ET = self.etree
4207 b = ET.TreeBuilder()
4208 self.assertEqual(b.comment('ctext').tag, ET.Comment)
4209 self.assertEqual(b.comment('ctext').text, 'ctext')
4210
4211 b = ET.TreeBuilder(comment_factory=ET.Comment)
4212 self.assertEqual(b.comment('ctext').tag, ET.Comment)
4213 self.assertEqual(b.comment('ctext').text, 'ctext')
4214
4215 #b = ET.TreeBuilder(comment_factory=len)
4216 #self.assertEqual(b.comment('ctext'), len('ctext'))
4217
4218 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4220 ET = self.etree
4221 is_lxml = ET.__name__ == 'lxml.etree'
4222
4223 b = ET.TreeBuilder()
4224 self.assertEqual(b.pi('target', None).tag, ET.PI)
4225 if is_lxml:
4226 self.assertEqual(b.pi('target', None).target, 'target')
4227 else:
4228 self.assertEqual(b.pi('target', None).text, 'target')
4229
4230 b = ET.TreeBuilder(pi_factory=ET.PI)
4231 self.assertEqual(b.pi('target').tag, ET.PI)
4232 if is_lxml:
4233 self.assertEqual(b.pi('target').target, "target")
4234 else:
4235 self.assertEqual(b.pi('target').text, "target")
4236 self.assertEqual(b.pi('pitarget', ' text ').tag, ET.PI)
4237 if is_lxml:
4238 self.assertEqual(b.pi('pitarget', ' text ').target, "pitarget")
4239 self.assertEqual(b.pi('pitarget', ' text ').text, " text ")
4240 else:
4241 self.assertEqual(b.pi('pitarget', ' text ').text, "pitarget text ")
4242
4243 #b = ET.TreeBuilder(pi_factory=lambda target, text: (len(target), text))
4244 #self.assertEqual(b.pi('target'), (len('target'), None))
4245 #self.assertEqual(b.pi('pitarget', ' text '), (len('pitarget'), ' text '))
4246
4248 # Issue #37399: The tail of an ignored comment could overwrite the text before it.
4249 ET = self.etree
4250 class TreeBuilderSubclass(ET.TreeBuilder):
4251 pass
4252
4253 if ET.__name__ == 'lxml.etree':
4254 def assert_content(a):
4255 self.assertEqual(a.text, "text")
4256 self.assertEqual(a[0].tail, "tail")
4257 else:
4258 def assert_content(a):
4259 self.assertEqual(a.text, "texttail")
4260
4261 xml = "<a>text<!-- comment -->tail</a>"
4262 a = ET.fromstring(xml)
4263 assert_content(a)
4264
4265 parser = ET.XMLParser(target=TreeBuilderSubclass())
4266 parser.feed(xml)
4267 a = parser.close()
4268 assert_content(a)
4269
4270 xml = "<a>text<?pi data?>tail</a>"
4271 a = ET.fromstring(xml)
4272 assert_content(a)
4273
4274 xml = "<a>text<?pi data?>tail</a>"
4275 parser = ET.XMLParser(target=TreeBuilderSubclass())
4276 parser.feed(xml)
4277 a = parser.close()
4278 assert_content(a)
4279
4280 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4282 # Issue #37399: The tail of an ignored comment could overwrite the text before it.
4283 # Test appending tails to comments/pis.
4284 ET = self.etree
4285 class TreeBuilderSubclass(ET.TreeBuilder):
4286 pass
4287
4288 xml = "<a>text<?pi1?> <!-- comment -->\n<?pi2?>tail</a>"
4289 parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True, insert_pis=False))
4290 parser.feed(xml)
4291 a = parser.close()
4292 self.assertEqual(a[0].text, ' comment ')
4293 self.assertEqual(a[0].tail, '\ntail')
4294 self.assertEqual(a.text, "text ")
4295
4296 parser = ET.XMLParser(target=TreeBuilderSubclass(insert_comments=True, insert_pis=False))
4297 parser.feed(xml)
4298 a = parser.close()
4299 self.assertEqual(a[0].text, ' comment ')
4300 self.assertEqual(a[0].tail, '\ntail')
4301 self.assertEqual(a.text, "text ")
4302
4303 xml = "<a>text<!-- comment -->\n<?pi data?>tail</a>"
4304 parser = ET.XMLParser(target=ET.TreeBuilder(insert_pis=True, insert_comments=False))
4305 parser.feed(xml)
4306 a = parser.close()
4307 self.assertEqual(a[0].text[-4:], 'data')
4308 self.assertEqual(a[0].tail, 'tail')
4309 self.assertEqual(a.text, "text\n")
4310
4311 parser = ET.XMLParser(target=TreeBuilderSubclass(insert_pis=True, insert_comments=False))
4312 parser.feed(xml)
4313 a = parser.close()
4314 self.assertEqual(a[0].text[-4:], 'data')
4315 self.assertEqual(a[0].tail, 'tail')
4316 self.assertEqual(a.text, "text\n")
4317
4318 # helper methods
4319
4321 """Write out element for comparison.
4322 """
4323 data = self.etree.tostring(element, encoding=encoding)
4324 return canonicalize(data)
4325
4327 """Write out element for comparison, using real file.
4328 """
4329 ElementTree = self.etree.ElementTree
4330 with tmpfile() as filename:
4331 with open(filename, 'wb') as f:
4332 tree = ElementTree(element=element)
4333 tree.write(f, encoding=encoding)
4334 with open(filename, 'rb') as f:
4335 data = f.read()
4336 return canonicalize(data)
4337
4339 """Writes element out and checks whether it is expected.
4340
4341 Does this two ways; once using BytesIO, once using a real file.
4342 """
4343 if isinstance(expected, unicode):
4344 expected = expected.encode(encoding)
4345 self.assertEqual(expected, self._writeElement(element, encoding))
4346 self.assertEqual(expected, self._writeElementFile(element, encoding))
4347
4349 "Checks if the result XML byte string specifies the encoding."
4350 enc_re = r"<\?xml[^>]+ encoding=[\"']([^\"']+)[\"']"
4351 if isinstance(result, str):
4352 has_encoding = re.compile(enc_re).match
4353 else:
4354 has_encoding = re.compile(_bytes(enc_re)).match
4355 self.assertTrue(has_encoding(result))
4356 result_encoding = has_encoding(result).group(1)
4357 self.assertEqual(result_encoding.upper(), encoding.upper())
4358
4360 return self.etree.tostring(tree.getroot()).replace(
4361 _bytes(' '), _bytes('')).replace(_bytes('\n'), _bytes(''))
4362
4365
4367 self.assertTrue(hasattr(element, 'tag'))
4368 self.assertTrue(hasattr(element, 'attrib'))
4369 self.assertTrue(hasattr(element, 'text'))
4370 self.assertTrue(hasattr(element, 'tail'))
4371 self._check_string(element.tag)
4372 self._check_mapping(element.attrib)
4373 if element.text is not None:
4374 self._check_string(element.text)
4375 if element.tail is not None:
4376 self._check_string(element.tail)
4377
4379 len(string)
4380 for char in string:
4381 self.assertEqual(1, len(char))
4382 new_string = string + ""
4383 new_string = string + " "
4384 string[:0]
4385
4387 len(mapping)
4388 keys = mapping.keys()
4389 values = mapping.values()
4390 items = mapping.items()
4391 for key in keys:
4392 item = mapping[key]
4393 mapping["key"] = "value"
4394 self.assertEqual("value", mapping["key"])
4395
4398 etree = None
4399
4402
4405
4407 """Create an Element with a tag 'a', with the given amount of children
4408 named 'a0', 'a1' ... and so on.
4409
4410 """
4411 e = self.etree.Element('a')
4412 for i in range(numchildren):
4413 self.etree.SubElement(e, 'a%s' % i)
4414 return e
4415
4417 e = self._make_elem_with_children(10)
4418
4419 self.assertEqual(e[1].tag, 'a1')
4420 self.assertEqual(e[-2].tag, 'a8')
4421
4422 self.assertRaises(IndexError, lambda: e[12])
4423 self.assertRaises(IndexError, lambda: e[-12])
4424
4426 e = self._make_elem_with_children(6)
4427
4428 self.assertEqual(self._elem_tags(e[3:]), ['a3', 'a4', 'a5'])
4429 self.assertEqual(self._elem_tags(e[3:6]), ['a3', 'a4', 'a5'])
4430 self.assertEqual(self._elem_tags(e[3:16]), ['a3', 'a4', 'a5'])
4431 self.assertEqual(self._elem_tags(e[3:5]), ['a3', 'a4'])
4432 self.assertEqual(self._elem_tags(e[3:-1]), ['a3', 'a4'])
4433 self.assertEqual(self._elem_tags(e[:2]), ['a0', 'a1'])
4434
4436 e = self._make_elem_with_children(10)
4437
4438 self.assertEqual(self._elem_tags(e[8:10:1]), ['a8', 'a9'])
4439 self.assertEqual(self._elem_tags(e[::3]), ['a0', 'a3', 'a6', 'a9'])
4440 self.assertEqual(self._elem_tags(e[::8]), ['a0', 'a8'])
4441 self.assertEqual(self._elem_tags(e[1::8]), ['a1', 'a9'])
4442 self.assertEqual(self._elem_tags(e[3::sys.maxsize]), ['a3'])
4443 self.assertEqual(self._elem_tags(e[3::sys.maxsize<<64]), ['a3'])
4444
4446 e = self._make_elem_with_children(4)
4447
4448 self.assertEqual(self._elem_tags(e[::-1]), ['a3', 'a2', 'a1', 'a0'])
4449 self.assertEqual(self._elem_tags(e[::-2]), ['a3', 'a1'])
4450 self.assertEqual(self._elem_tags(e[3::-sys.maxsize]), ['a3'])
4451 self.assertEqual(self._elem_tags(e[3::-sys.maxsize-1]), ['a3'])
4452 self.assertEqual(self._elem_tags(e[3::-sys.maxsize<<64]), ['a3'])
4453
4455 e = self._make_elem_with_children(4)
4456 del e[0:2]
4457 self.assertEqual(self._subelem_tags(e), ['a2', 'a3'])
4458
4459 e = self._make_elem_with_children(4)
4460 del e[0:]
4461 self.assertEqual(self._subelem_tags(e), [])
4462
4463 e = self._make_elem_with_children(4)
4464 del e[::-1]
4465 self.assertEqual(self._subelem_tags(e), [])
4466
4467 e = self._make_elem_with_children(4)
4468 del e[::-2]
4469 self.assertEqual(self._subelem_tags(e), ['a0', 'a2'])
4470
4471 e = self._make_elem_with_children(4)
4472 del e[1::2]
4473 self.assertEqual(self._subelem_tags(e), ['a0', 'a2'])
4474
4475 e = self._make_elem_with_children(2)
4476 del e[::2]
4477 self.assertEqual(self._subelem_tags(e), ['a1'])
4478
4480 e = self._make_elem_with_children(4)
4481 e[1] = self.etree.Element('b')
4482 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3'])
4483
4484 e[-2] = self.etree.Element('c')
4485 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3'])
4486
4487 with self.assertRaises(IndexError):
4488 e[5] = self.etree.Element('d')
4489 with self.assertRaises(IndexError):
4490 e[-5] = self.etree.Element('d')
4491 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3'])
4492
4494 e = self._make_elem_with_children(4)
4495 e[1:3] = [self.etree.Element('b%s' % i) for i in range(2)]
4496 self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'a3'])
4497
4498 e = self._make_elem_with_children(4)
4499 e[1:3] = [self.etree.Element('b')]
4500 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a3'])
4501
4502 e = self._make_elem_with_children(4)
4503 e[1:3] = [self.etree.Element('b%s' % i) for i in range(3)]
4504 self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'b2', 'a3'])
4505
4507 e = self._make_elem_with_children(6)
4508 e[1:5:2] = [self.etree.Element('b%s' % i) for i in range(2)]
4509 self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'a2', 'b1', 'a4', 'a5'])
4510
4511 e = self._make_elem_with_children(6)
4512 with self.assertRaises(ValueError):
4513 e[1:5:2] = [self.etree.Element('b')]
4514 with self.assertRaises(ValueError):
4515 e[1:5:2] = [self.etree.Element('b%s' % i) for i in range(3)]
4516 with self.assertRaises(ValueError):
4517 e[1:5:2] = []
4518 self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3', 'a4', 'a5'])
4519
4520 e = self._make_elem_with_children(4)
4521 e[1::sys.maxsize] = [self.etree.Element('b')]
4522 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3'])
4523 e[1::sys.maxsize<<64] = [self.etree.Element('c')]
4524 self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3'])
4525
4527 e = self._make_elem_with_children(4)
4528 e[2:0:-1] = [self.etree.Element('b%s' % i) for i in range(2)]
4529 self.assertEqual(self._subelem_tags(e), ['a0', 'b1', 'b0', 'a3'])
4530
4531 e = self._make_elem_with_children(4)
4532 with self.assertRaises(ValueError):
4533 e[2:0:-1] = [self.etree.Element('b')]
4534 with self.assertRaises(ValueError):
4535 e[2:0:-1] = [self.etree.Element('b%s' % i) for i in range(3)]
4536 with self.assertRaises(ValueError):
4537 e[2:0:-1] = []
4538 self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3'])
4539
4540 e = self._make_elem_with_children(4)
4541 e[1::-sys.maxsize] = [self.etree.Element('b')]
4542 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3'])
4543 e[1::-sys.maxsize-1] = [self.etree.Element('c')]
4544 self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3'])
4545 e[1::-sys.maxsize<<64] = [self.etree.Element('d')]
4546 self.assertEqual(self._subelem_tags(e), ['a0', 'd', 'a2', 'a3'])
4547
4550 etree = None
4551
4553 if 'ElementTree' in self.etree.__name__:
4554 # ElementTree's API is a bit unwieldy in Py3.4
4555 root = parser._close_and_return_root()
4556 else:
4557 root = parser.close()
4558 return root
4559
4561 if chunk_size is None:
4562 parser.feed(data)
4563 else:
4564 for i in range(0, len(data), chunk_size):
4565 parser.feed(data[i:i+chunk_size])
4566
4568 self.assertEqual(
4569 [(event, (elem.tag, elem.text))
4570 for event, elem in islice(parser.read_events(), max_events)],
4571 expected)
4572
4577
4582
4584 for chunk_size in (None, 1, 5):
4585 #with self.subTest(chunk_size=chunk_size):
4586 parser = self.etree.XMLPullParser()
4587 self.assert_event_tags(parser, [])
4588 self._feed(parser, "<!-- comment -->\n", chunk_size)
4589 self.assert_event_tags(parser, [])
4590 self._feed(parser,
4591 "<root>\n <element key='value'>text</element",
4592 chunk_size)
4593 self.assert_event_tags(parser, [])
4594 self._feed(parser, ">\n", chunk_size)
4595 self.assert_event_tags(parser, [('end', 'element')])
4596 self._feed(parser, "<element>text</element>tail\n", chunk_size)
4597 self._feed(parser, "<empty-element/>\n", chunk_size)
4598 self.assert_event_tags(parser, [
4599 ('end', 'element'),
4600 ('end', 'empty-element'),
4601 ])
4602 self._feed(parser, "</root>\n", chunk_size)
4603 self.assert_event_tags(parser, [('end', 'root')])
4604 root = self._close_and_return_root(parser)
4605 self.assertEqual(root.tag, 'root')
4606
4608 parser = self.etree.XMLPullParser()
4609 it = parser.read_events()
4610 self._feed(parser, "<root>\n <element key='value'>text</element>\n")
4611 action, elem = next(it)
4612 self.assertEqual((action, elem.tag), ('end', 'element'))
4613 self._feed(parser, "</root>\n")
4614 action, elem = next(it)
4615 self.assertEqual((action, elem.tag), ('end', 'root'))
4616 with self.assertRaises(StopIteration):
4617 next(it)
4618
4620 parser = self.etree.XMLPullParser()
4621 self.assert_event_tags(parser, [])
4622 self._feed(parser, "<!-- comment -->\n")
4623 self.assert_event_tags(parser, [])
4624 self._feed(parser, "<root xmlns='namespace'>\n")
4625 self.assert_event_tags(parser, [])
4626 self._feed(parser, "<element key='value'>text</element")
4627 self.assert_event_tags(parser, [])
4628 self._feed(parser, ">\n")
4629 self.assert_event_tags(parser, [('end', '{namespace}element')])
4630 self._feed(parser, "<element>text</element>tail\n")
4631 self._feed(parser, "<empty-element/>\n")
4632 self.assert_event_tags(parser, [
4633 ('end', '{namespace}element'),
4634 ('end', '{namespace}empty-element'),
4635 ])
4636 self._feed(parser, "</root>\n")
4637 self.assert_event_tags(parser, [('end', '{namespace}root')])
4638 root = self._close_and_return_root(parser)
4639 self.assertEqual(root.tag, '{namespace}root')
4640
4642 parser = self.etree.XMLPullParser(events=('start-ns', 'end-ns'))
4643 self._feed(parser, "<!-- comment -->\n")
4644 self._feed(parser, "<root xmlns='namespace'>\n")
4645 self.assertEqual(
4646 list(parser.read_events()),
4647 [('start-ns', ('', 'namespace'))])
4648 self._feed(parser, "<element key='value'>text</element")
4649 self._feed(parser, ">\n")
4650 self._feed(parser, "<element>text</element>tail\n")
4651 self._feed(parser, "<empty-element/>\n")
4652 self._feed(parser, "</root>\n")
4653 self.assertEqual(list(parser.read_events()), [('end-ns', None)])
4654 parser.close()
4655
4657 parser = self.etree.XMLPullParser(events=['end-ns'])
4658 self._feed(parser, "<!-- comment -->\n")
4659 self._feed(parser, "<root xmlns='namespace' xmlns:a='abc' xmlns:b='xyz'>\n")
4660 self.assertEqual(list(parser.read_events()), [])
4661 self._feed(parser, "<a:element key='value'>text</a:element")
4662 self._feed(parser, ">\n")
4663 self._feed(parser, "<b:element>text</b:element>tail\n")
4664 self._feed(parser, "<empty-element/>\n")
4665 self.assertEqual(list(parser.read_events()), [])
4666 self._feed(parser, "</root>\n")
4667 self.assertEqual(list(parser.read_events()), [
4668 ('end-ns', None),
4669 ('end-ns', None),
4670 ('end-ns', None),
4671 ])
4672 parser.close()
4673
4674 @et_needs_pyversion(3,8)
4676 parser = self.etree.XMLPullParser(events=('start-ns', 'start', 'end'))
4677 self._feed(parser, "<tag xmlns='abc' xmlns:p='xyz'>\n")
4678 self.assert_event_tuples(parser, [
4679 ('start-ns', ('', 'abc')),
4680 ('start-ns', ('p', 'xyz')),
4681 ], max_events=2)
4682 self.assert_event_tags(parser, [
4683 ('start', '{abc}tag'),
4684 ], max_events=1)
4685
4686 self._feed(parser, "<child />\n")
4687 self.assert_event_tags(parser, [
4688 ('start', '{abc}child'),
4689 ('end', '{abc}child'),
4690 ])
4691
4692 self._feed(parser, "</tag>\n")
4693 parser.close()
4694 self.assert_event_tags(parser, [
4695 ('end', '{abc}tag'),
4696 ])
4697
4698 @et_needs_pyversion(3,8)
4700 parser = self.etree.XMLPullParser(events=('start-ns', 'start', 'end', 'end-ns'))
4701 self._feed(parser, "<tag xmlns='abc' xmlns:p='xyz'>\n")
4702 self.assert_event_tuples(parser, [
4703 ('start-ns', ('', 'abc')),
4704 ('start-ns', ('p', 'xyz')),
4705 ], max_events=2)
4706 self.assert_event_tags(parser, [
4707 ('start', '{abc}tag'),
4708 ], max_events=1)
4709
4710 self._feed(parser, "<child />\n")
4711 self.assert_event_tags(parser, [
4712 ('start', '{abc}child'),
4713 ('end', '{abc}child'),
4714 ])
4715
4716 self._feed(parser, "</tag>\n")
4717 parser.close()
4718 self.assert_event_tags(parser, [
4719 ('end', '{abc}tag'),
4720 ], max_events=1)
4721 self.assert_event_tuples(parser, [
4722 ('end-ns', None),
4723 ('end-ns', None),
4724 ])
4725
4727 parser = self.etree.XMLPullParser(events=())
4728 self._feed(parser, "<root/>\n")
4729 self.assert_event_tags(parser, [])
4730
4731 parser = self.etree.XMLPullParser(events=('start', 'end'))
4732 self._feed(parser, "<!-- text here -->\n")
4733 self.assert_events(parser, [])
4734
4735 parser = self.etree.XMLPullParser(events=('start', 'end'))
4736 self._feed(parser, "<root>\n")
4737 self.assert_event_tags(parser, [('start', 'root')])
4738 self._feed(parser, "<element key='value'>text</element")
4739 self.assert_event_tags(parser, [('start', 'element')])
4740 self._feed(parser, ">\n")
4741 self.assert_event_tags(parser, [('end', 'element')])
4742 self._feed(parser,
4743 "<element xmlns='foo'>text<empty-element/></element>tail\n")
4744 self.assert_event_tags(parser, [
4745 ('start', '{foo}element'),
4746 ('start', '{foo}empty-element'),
4747 ('end', '{foo}empty-element'),
4748 ('end', '{foo}element'),
4749 ])
4750 self._feed(parser, "</root>")
4751 root = self._close_and_return_root(parser)
4752 self.assert_event_tags(parser, [('end', 'root')])
4753 self.assertEqual(root.tag, 'root')
4754
4755 parser = self.etree.XMLPullParser(events=('start',))
4756 self._feed(parser, "<!-- comment -->\n")
4757 self.assert_event_tags(parser, [])
4758 self._feed(parser, "<root>\n")
4759 self.assert_event_tags(parser, [('start', 'root')])
4760 self._feed(parser, "<element key='value'>text</element")
4761 self.assert_event_tags(parser, [('start', 'element')])
4762 self._feed(parser, ">\n")
4763 self.assert_event_tags(parser, [])
4764 self._feed(parser,
4765 "<element xmlns='foo'>text<empty-element/></element>tail\n")
4766 self.assert_event_tags(parser, [
4767 ('start', '{foo}element'),
4768 ('start', '{foo}empty-element'),
4769 ])
4770 self._feed(parser, "</root>")
4771 root = self._close_and_return_root(parser)
4772 self.assertEqual(root.tag, 'root')
4773
4774 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4776 parser = self.etree.XMLPullParser(events=('start', 'comment', 'end'))
4777 self._feed(parser, "<!-- text here -->\n")
4778 self.assert_events(parser, [('comment', (self.etree.Comment, ' text here '))])
4779 self._feed(parser, "<!-- more text here -->\n")
4780 self.assert_events(parser, [('comment', (self.etree.Comment, ' more text here '))])
4781 self._feed(parser, "<root-tag>text")
4782 self.assert_event_tags(parser, [('start', 'root-tag')])
4783 self._feed(parser, "<!-- inner comment-->\n")
4784 self.assert_events(parser, [('comment', (self.etree.Comment, ' inner comment'))])
4785 self._feed(parser, "</root-tag>\n")
4786 self.assert_event_tags(parser, [('end', 'root-tag')])
4787 self._feed(parser, "<!-- outer comment -->\n")
4788 self.assert_events(parser, [('comment', (self.etree.Comment, ' outer comment '))])
4789
4790 parser = self.etree.XMLPullParser(events=('comment',))
4791 self._feed(parser, "<!-- text here -->\n")
4792 self.assert_events(parser, [('comment', (self.etree.Comment, ' text here '))])
4793
4794 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4796 # Note: lxml's PIs have target+text, ET's PIs have both in "text"
4797 parser = self.etree.XMLPullParser(events=('start', 'pi', 'end'))
4798 self._feed(parser, "<?pitarget?>\n")
4799 self.assert_event_tags(parser, [('pi', self.etree.PI)])
4800 parser = self.etree.XMLPullParser(events=('pi',))
4801 self._feed(parser, "<?pitarget some text ?>\n")
4802 self.assert_event_tags(parser, [('pi', self.etree.PI)])
4803
4805 # Test that events can be some sequence that's not just a tuple or list
4806 eventset = {'end', 'start'}
4807 parser = self.etree.XMLPullParser(events=eventset)
4808 self._feed(parser, "<foo>bar</foo>")
4809 self.assert_event_tags(parser, [('start', 'foo'), ('end', 'foo')])
4810
4811 class DummyIter(object):
4812 def __init__(self):
4813 self.events = iter(['start', 'end', 'start-ns'])
4814 def __iter__(self):
4815 return self
4816 def __next__(self):
4817 return next(self.events)
4818 def next(self):
4819 return next(self.events)
4820
4821 parser = self.etree.XMLPullParser(events=DummyIter())
4822 self._feed(parser, "<foo>bar</foo>")
4823 self.assert_event_tags(parser, [('start', 'foo'), ('end', 'foo')])
4824
4826 with self.assertRaises(ValueError):
4827 self.etree.XMLPullParser(events=('start', 'end', 'bogus'))
4828
4831 etree = None
4832 maxDiff = None
4833
4834 if not hasattr(unittest.TestCase, 'subTest'):
4835 @contextmanager
4837 try:
4838 yield
4839 except unittest.SkipTest:
4840 raise
4841 except Exception as e:
4842 print("Subtest {} failed: {}".format(name, e))
4843 raise
4844
4847
4848 #
4849 # simple roundtrip tests (from c14n.py)
4850
4853
4855 c14n_roundtrip = self.c14n_roundtrip
4856 # Basics
4857 self.assertEqual(c14n_roundtrip("<doc/>"), '<doc></doc>')
4858 self.assertEqual(c14n_roundtrip("<doc xmlns='uri'/>"), # FIXME
4859 '<doc xmlns="uri"></doc>')
4860 self.assertEqual(c14n_roundtrip("<prefix:doc xmlns:prefix='uri'/>"),
4861 '<prefix:doc xmlns:prefix="uri"></prefix:doc>')
4862 self.assertEqual(c14n_roundtrip("<doc xmlns:prefix='uri'><prefix:bar/></doc>"),
4863 '<doc><prefix:bar xmlns:prefix="uri"></prefix:bar></doc>')
4864 self.assertEqual(c14n_roundtrip("<elem xmlns:wsu='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd' xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' />"),
4865 '<elem></elem>')
4866
4867 # C14N spec
4868 self.assertEqual(c14n_roundtrip("<doc>Hello, world!<!-- Comment 1 --></doc>"),
4869 '<doc>Hello, world!</doc>')
4870 self.assertEqual(c14n_roundtrip("<value>2</value>"),
4871 '<value>2</value>')
4872 self.assertEqual(c14n_roundtrip('<compute><![CDATA[value>"0" && value<"10" ?"valid":"error"]]></compute>'),
4873 '<compute>value>"0" && value<"10" ?"valid":"error"</compute>')
4874 self.assertEqual(c14n_roundtrip('''<compute expr='value>"0" && value<"10" ?"valid":"error"'>valid</compute>'''),
4875 '<compute expr="value>"0" && value<"10" ?"valid":"error"">valid</compute>')
4876 self.assertEqual(c14n_roundtrip("<norm attr=' '   
	 ' '/>"),
4877 '<norm attr=" \' 
	 \' "></norm>')
4878 self.assertEqual(c14n_roundtrip("<normNames attr=' A   
	 B '/>"),
4879 '<normNames attr=" A 
	 B "></normNames>')
4880 self.assertEqual(c14n_roundtrip("<normId id=' '   
	 ' '/>"),
4881 '<normId id=" \' 
	 \' "></normId>')
4882
4883 # fragments from PJ's tests
4884 #self.assertEqual(c14n_roundtrip("<doc xmlns:x='http://example.com/x' xmlns='http://example.com/default'><b y:a1='1' xmlns='http://example.com/default' a3='3' xmlns:y='http://example.com/y' y:a2='2'/></doc>"),
4885 #'<doc xmlns:x="http://example.com/x"><b xmlns:y="http://example.com/y" a3="3" y:a1="1" y:a2="2"></b></doc>')
4886
4888 c14n_roundtrip = self.c14n_roundtrip
4889 xml = textwrap.dedent("""\
4890 <root xmlns:x="http://example.com/x">
4891 <a x:attr="attrx">
4892 <b>abtext</b>
4893 </a>
4894 <b>btext</b>
4895 <c>
4896 <x:d>dtext</x:d>
4897 </c>
4898 </root>
4899 """)
4900 self.assertEqual(
4901 c14n_roundtrip(xml, strip_text=True),
4902 '<root>'
4903 '<a xmlns:x="http://example.com/x" x:attr="attrx"><b>abtext</b></a>'
4904 '<b>btext</b>'
4905 '<c><x:d xmlns:x="http://example.com/x">dtext</x:d></c>'
4906 '</root>')
4907 self.assertEqual(
4908 c14n_roundtrip(xml, strip_text=True, exclude_attrs=['{http://example.com/x}attr']),
4909 '<root>'
4910 '<a><b>abtext</b></a>'
4911 '<b>btext</b>'
4912 '<c><x:d xmlns:x="http://example.com/x">dtext</x:d></c>'
4913 '</root>')
4914 self.assertEqual(
4915 c14n_roundtrip(xml, strip_text=True, exclude_tags=['{http://example.com/x}d']),
4916 '<root>'
4917 '<a xmlns:x="http://example.com/x" x:attr="attrx"><b>abtext</b></a>'
4918 '<b>btext</b>'
4919 '<c></c>'
4920 '</root>')
4921 self.assertEqual(
4922 c14n_roundtrip(xml, strip_text=True, exclude_attrs=['{http://example.com/x}attr'],
4923 exclude_tags=['{http://example.com/x}d']),
4924 '<root>'
4925 '<a><b>abtext</b></a>'
4926 '<b>btext</b>'
4927 '<c></c>'
4928 '</root>')
4929 self.assertEqual(
4930 c14n_roundtrip(xml, strip_text=True, exclude_tags=['a', 'b']),
4931 '<root>'
4932 '<c><x:d xmlns:x="http://example.com/x">dtext</x:d></c>'
4933 '</root>')
4934 self.assertEqual(
4935 c14n_roundtrip(xml, exclude_tags=['a', 'b']),
4936 '<root>\n'
4937 ' \n'
4938 ' \n'
4939 ' <c>\n'
4940 ' <x:d xmlns:x="http://example.com/x">dtext</x:d>\n'
4941 ' </c>\n'
4942 '</root>')
4943 self.assertEqual(
4944 c14n_roundtrip(xml, strip_text=True, exclude_tags=['{http://example.com/x}d', 'b']),
4945 '<root>'
4946 '<a xmlns:x="http://example.com/x" x:attr="attrx"></a>'
4947 '<c></c>'
4948 '</root>')
4949 self.assertEqual(
4950 c14n_roundtrip(xml, exclude_tags=['{http://example.com/x}d', 'b']),
4951 '<root>\n'
4952 ' <a xmlns:x="http://example.com/x" x:attr="attrx">\n'
4953 ' \n'
4954 ' </a>\n'
4955 ' \n'
4956 ' <c>\n'
4957 ' \n'
4958 ' </c>\n'
4959 '</root>')
4960
4961 #
4962 # basic method=c14n tests from the c14n 2.0 specification. uses
4963 # test files under xmltestdata/c14n-20.
4964
4965 # note that this uses generated C14N versions of the standard ET.write
4966 # output, not roundtripped C14N (see above).
4967
4969 datadir = os.path.join(os.path.dirname(__file__), "c14n-20")
4970 full_path = partial(os.path.join, datadir)
4971
4972 files = [filename[:-4] for filename in sorted(os.listdir(datadir))
4973 if filename.endswith('.xml')]
4974 input_files = [
4975 filename for filename in files
4976 if filename.startswith('in')
4977 ]
4978 configs = {
4979 filename: {
4980 # <c14n2:PrefixRewrite>sequential</c14n2:PrefixRewrite>
4981 option.tag.split('}')[-1]: ((option.text or '').strip(), option)
4982 for option in self.etree.parse(full_path(filename) + ".xml").getroot()
4983 }
4984 for filename in files
4985 if filename.startswith('c14n')
4986 }
4987
4988 tests = {
4989 input_file: [
4990 (filename, configs[filename.rsplit('_', 1)[-1]])
4991 for filename in files
4992 if filename.startswith('out_%s_' % input_file)
4993 and filename.rsplit('_', 1)[-1] in configs
4994 ]
4995 for input_file in input_files
4996 }
4997
4998 # Make sure we found all test cases.
4999 self.assertEqual(30, len([
5000 output_file for output_files in tests.values()
5001 for output_file in output_files]))
5002
5003 def get_option(config, option_name, default=None):
5004 return config.get(option_name, (default, ()))[0]
5005
5006 for input_file, output_files in tests.items():
5007 for output_file, config in output_files:
5008 keep_comments = get_option(
5009 config, 'IgnoreComments') == 'true' # no, it's right :)
5010 strip_text = get_option(
5011 config, 'TrimTextNodes') == 'true'
5012 rewrite_prefixes = get_option(
5013 config, 'PrefixRewrite') == 'sequential'
5014 if 'QNameAware' in config:
5015 qattrs = [
5016 "{%s}%s" % (el.get('NS'), el.get('Name'))
5017 for el in config['QNameAware'][1].findall(
5018 '{http://www.w3.org/2010/xml-c14n2}QualifiedAttr')
5019 ]
5020 qtags = [
5021 "{%s}%s" % (el.get('NS'), el.get('Name'))
5022 for el in config['QNameAware'][1].findall(
5023 '{http://www.w3.org/2010/xml-c14n2}Element')
5024 ]
5025 else:
5026 qtags = qattrs = None
5027
5028 # Build subtest description from config.
5029 config_descr = ','.join(
5030 "%s=%s" % (name, value or ','.join(c.tag.split('}')[-1] for c in children))
5031 for name, (value, children) in sorted(config.items())
5032 )
5033
5034 with self.subTest("{}({})".format(output_file, config_descr)):
5035 if input_file == 'inNsRedecl' and not rewrite_prefixes:
5036 self.skipTest(
5037 "Redeclared namespace handling is not supported in {}".format(
5038 output_file))
5039 if input_file == 'inNsSuperfluous' and not rewrite_prefixes:
5040 self.skipTest(
5041 "Redeclared namespace handling is not supported in {}".format(
5042 output_file))
5043 if 'QNameAware' in config and config['QNameAware'][1].find(
5044 '{http://www.w3.org/2010/xml-c14n2}XPathElement') is not None:
5045 self.skipTest(
5046 "QName rewriting in XPath text is not supported in {}".format(
5047 output_file))
5048
5049 f = full_path(input_file + ".xml")
5050 if input_file == 'inC14N5':
5051 # Hack: avoid setting up external entity resolution in the parser.
5052 with open(full_path('world.txt'), 'rb') as entity_file:
5053 with open(f, 'rb') as f:
5054 f = io.BytesIO(f.read().replace(b'&ent2;', entity_file.read().strip()))
5055
5056 text = self._canonicalize(
5057 f,
5058 with_comments=keep_comments,
5059 strip_text=strip_text,
5060 rewrite_prefixes=rewrite_prefixes,
5061 qname_aware_tags=qtags, qname_aware_attrs=qattrs)
5062
5063 with io.open(full_path(output_file + ".xml"), 'r', encoding='utf8') as f:
5064 expected = f.read()
5065 if input_file == 'inC14N3' and self.etree is not etree:
5066 # FIXME: cET resolves default attributes but ET does not!
5067 expected = expected.replace(' attr="default"', '')
5068 text = text.replace(' attr="default"', '')
5069 self.assertEqual(expected, text)
5070
5071
5072 if etree:
5075
5078
5081
5084
5086 - def _canonicalize(self, input_file, with_comments=True, strip_text=False,
5087 rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None,
5088 **options):
5089 if rewrite_prefixes or qname_aware_attrs or qname_aware_tags:
5090 self.skipTest("C14N 2.0 feature not supported with ElementTree.write()")
5091
5092 parser = self.etree.XMLParser(attribute_defaults=True, collect_ids=False)
5093 tree = self.etree.parse(input_file, parser)
5094 out = io.BytesIO()
5095 tree.write(
5096 out, method='c14n2',
5097 with_comments=with_comments, strip_text=strip_text,
5098 **options)
5099 return out.getvalue().decode('utf8')
5100
5102 - def _canonicalize(self, input_file, with_comments=True, strip_text=False,
5103 rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None,
5104 **options):
5105 if rewrite_prefixes or qname_aware_attrs or qname_aware_tags:
5106 self.skipTest("C14N 2.0 feature not supported with ElementTree.tostring()")
5107
5108 parser = self.etree.XMLParser(attribute_defaults=True, collect_ids=False)
5109 tree = self.etree.parse(input_file, parser)
5110 return self.etree.tostring(
5111 tree, method='c14n2',
5112 with_comments=with_comments, strip_text=strip_text,
5113 **options).decode('utf8')
5114
5115
5116 if ElementTree:
5128
5129 filter_by_version(
5130 ElementTreeTestCase,
5131 ElementTreeTestCase.required_versions_ET, ET_VERSION)
5132
5133 if hasattr(ElementTree, 'XMLPullParser'):
5136 else:
5137 ElementTreePullTestCase = None
5138
5139 if hasattr(ElementTree, 'canonicalize'):
5142 else:
5143 ElementTreeC14NTest = None
5147
5148
5149 if cElementTree:
5152
5153 filter_by_version(
5154 CElementTreeTestCase,
5155 CElementTreeTestCase.required_versions_cET, CET_VERSION)
5159
5162 suite = unittest.TestSuite()
5163 if etree:
5164 suite.addTests([unittest.makeSuite(ETreeTestCase)])
5165 suite.addTests([unittest.makeSuite(ETreePullTestCase)])
5166 suite.addTests([unittest.makeSuite(ETreeElementSlicingTest)])
5167 suite.addTests([unittest.makeSuite(ETreeC14NTest)])
5168 suite.addTests([unittest.makeSuite(ETreeC14N2WriteTest)])
5169 suite.addTests([unittest.makeSuite(ETreeC14N2TostringTest)])
5170 if ElementTree:
5171 suite.addTests([unittest.makeSuite(ElementTreeTestCase)])
5172 if ElementTreePullTestCase:
5173 suite.addTests([unittest.makeSuite(ElementTreePullTestCase)])
5174 if ElementTreeC14NTest:
5175 suite.addTests([unittest.makeSuite(ElementTreeC14NTest)])
5176 suite.addTests([unittest.makeSuite(ElementTreeElementSlicingTest)])
5177 if cElementTree:
5178 suite.addTests([unittest.makeSuite(CElementTreeTestCase)])
5179 suite.addTests([unittest.makeSuite(CElementTreeElementSlicingTest)])
5180 return suite
5181
5182 if __name__ == '__main__':
5183 print('to test use test.py %s' % __file__)
5184
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Wed Jan 29 09:44:05 2020 | http://epydoc.sourceforge.net |