| 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 import copy
12 import io
13 import operator
14 import os
15 import re
16 import sys
17 import textwrap
18 import unittest
19 from contextlib import contextmanager
20 from functools import wraps, partial
21 from itertools import islice
22
23 this_dir = os.path.dirname(__file__)
24 if this_dir not in sys.path:
25 sys.path.insert(0, this_dir) # needed for Py3
26
27 from common_imports import BytesIO, etree, HelperTestCase
28 from common_imports import ElementTree, cElementTree, ET_VERSION, CET_VERSION
29 from common_imports import filter_by_version, fileInTestDir, canonicalize, tmpfile
30 from common_imports import _str, _bytes, unicode, next, IS_PYTHON2
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 Element = self.etree.Element
1704
1705 a = Element('a')
1706 a.text = 'foo'
1707 a.tail = 'bar'
1708 a.set('hoi', 'dag')
1709 a.clear()
1710 self.assertEqual(None, a.text)
1711 self.assertEqual(None, a.tail)
1712 self.assertEqual(None, a.get('hoi'))
1713 self.assertEqual('a', a.tag)
1714
1716 Element = self.etree.Element
1717 SubElement = self.etree.SubElement
1718
1719 a = Element('a')
1720 a.text = 'foo'
1721 a.tail = 'bar'
1722 a.set('hoi', 'dag')
1723 b = SubElement(a, 'b')
1724 c = SubElement(b, 'c')
1725 a.clear()
1726 self.assertEqual(None, a.text)
1727 self.assertEqual(None, a.tail)
1728 self.assertEqual(None, a.get('hoi'))
1729 self.assertEqual('a', a.tag)
1730 self.assertEqual(0, len(a))
1731 self.assertXML(_bytes('<a></a>'),
1732 a)
1733 self.assertXML(_bytes('<b><c></c></b>'),
1734 b)
1735
1737 ElementTree = self.etree.ElementTree
1738 f = BytesIO('<a><b></b>B2<c></c>C2</a>')
1739 doc = ElementTree(file=f)
1740 a = doc.getroot()
1741 a.clear()
1742 self.assertXML(
1743 _bytes('<a></a>'),
1744 a)
1745
1747 Element = self.etree.Element
1748 SubElement = self.etree.SubElement
1749
1750 a = Element('a')
1751 b = SubElement(a, 'b')
1752 c = SubElement(a, 'c')
1753 d = Element('d')
1754 a.insert(0, d)
1755
1756 self.assertEqual(
1757 d,
1758 a[0])
1759
1760 self.assertXML(
1761 _bytes('<a><d></d><b></b><c></c></a>'),
1762 a)
1763
1764 e = Element('e')
1765 a.insert(2, e)
1766 self.assertEqual(
1767 e,
1768 a[2])
1769 self.assertXML(
1770 _bytes('<a><d></d><b></b><e></e><c></c></a>'),
1771 a)
1772
1774 # See GH#268 / LP#1773749.
1775 Element = self.etree.Element
1776 SubElement = self.etree.SubElement
1777
1778 # Use unique names to make sure they are new in the tag name dict.
1779 import uuid
1780 names = dict((k, 'tag-' + str(uuid.uuid4())) for k in 'abcde')
1781
1782 a = Element(names['a'])
1783 b = SubElement(a, names['b'])
1784 c = SubElement(a, names['c'])
1785 d = Element(names['d'])
1786 a.insert(0, d)
1787
1788 self.assertEqual(
1789 d,
1790 a[0])
1791
1792 self.assertXML(
1793 _bytes('<%(a)s><%(d)s></%(d)s><%(b)s></%(b)s><%(c)s></%(c)s></%(a)s>' % names),
1794 a)
1795
1796 e = Element(names['e'])
1797 a.insert(2, e)
1798 self.assertEqual(
1799 e,
1800 a[2])
1801 self.assertXML(
1802 _bytes('<%(a)s><%(d)s></%(d)s><%(b)s></%(b)s><%(e)s></%(e)s><%(c)s></%(c)s></%(a)s>' % names),
1803 a)
1804
1806 Element = self.etree.Element
1807 SubElement = self.etree.SubElement
1808
1809 a = Element('a')
1810 b = SubElement(a, 'b')
1811 c = Element('c')
1812
1813 a.insert(2, c)
1814 self.assertEqual(
1815 c,
1816 a[1])
1817 self.assertXML(
1818 _bytes('<a><b></b><c></c></a>'),
1819 a)
1820
1822 Element = self.etree.Element
1823 SubElement = self.etree.SubElement
1824
1825 a = Element('a')
1826 b = SubElement(a, 'b')
1827 c = SubElement(a, 'c')
1828
1829 d = Element('d')
1830 a.insert(-1, d)
1831 self.assertEqual(
1832 d,
1833 a[-2])
1834 self.assertXML(
1835 _bytes('<a><b></b><d></d><c></c></a>'),
1836 a)
1837
1839 Element = self.etree.Element
1840 SubElement = self.etree.SubElement
1841
1842 a = Element('a')
1843 b = SubElement(a, 'b')
1844
1845 c = Element('c')
1846 c.tail = 'C2'
1847
1848 a.insert(0, c)
1849 self.assertXML(
1850 _bytes('<a><c></c>C2<b></b></a>'),
1851 a)
1852
1854 Element = self.etree.Element
1855 SubElement = self.etree.SubElement
1856
1857 a = Element('a')
1858 b = SubElement(a, 'b')
1859 c = SubElement(a, 'c')
1860
1861 a.remove(b)
1862 self.assertEqual(
1863 c,
1864 a[0])
1865 self.assertXML(
1866 _bytes('<a><c></c></a>'),
1867 a)
1868
1870 Element = self.etree.Element
1871 SubElement = self.etree.SubElement
1872
1873 a = Element('{http://test}a')
1874 b = SubElement(a, '{http://test}b')
1875 c = SubElement(a, '{http://test}c')
1876
1877 a.remove(b)
1878 self.assertXML(
1879 _bytes('<ns0:a xmlns:ns0="http://test"><ns0:c></ns0:c></ns0:a>'),
1880 a)
1881 self.assertXML(
1882 _bytes('<ns0:b xmlns:ns0="http://test"></ns0:b>'),
1883 b)
1884
1886 Element = self.etree.Element
1887 SubElement = self.etree.SubElement
1888
1889 a = Element('a')
1890 b = SubElement(a, 'b')
1891 c = SubElement(a, 'c')
1892 d = Element('d')
1893 self.assertRaises(
1894 ValueError, a.remove, d)
1895
1897 Element = self.etree.Element
1898 SubElement = self.etree.SubElement
1899
1900 a = Element('a')
1901 b = SubElement(a, 'b')
1902 b.tail = 'b2'
1903 a.remove(b)
1904 self.assertXML(
1905 _bytes('<a></a>'),
1906 a)
1907 self.assertEqual('b2', b.tail)
1908
1910 # There is no guarantee that this "works", but it should
1911 # remove at least one child and not crash.
1912 Element = self.etree.Element
1913 SubElement = self.etree.SubElement
1914
1915 a = Element('a')
1916 SubElement(a, 'b')
1917 SubElement(a, 'c')
1918 SubElement(a, 'd')
1919 for el in a:
1920 a.remove(el)
1921 self.assertLess(len(a), 3)
1922
1924 Element = self.etree.Element
1925 SubElement = self.etree.SubElement
1926
1927 a = Element('a')
1928 b = SubElement(a, 'b')
1929 c = SubElement(a, 'c')
1930 d = SubElement(b, 'd')
1931 e = SubElement(c, 'e')
1932 self.assertXML(
1933 _bytes('<a><b><d></d></b><c><e></e></c></a>'),
1934 a)
1935 self.assertEqual(
1936 [b, c],
1937 a.getchildren())
1938 self.assertEqual(
1939 [d],
1940 b.getchildren())
1941 self.assertEqual(
1942 [],
1943 d.getchildren())
1944
1946 Element = self.etree.Element
1947
1948 a = Element('a')
1949 b = a.makeelement('c', {'hoi':'dag'})
1950 self.assertXML(
1951 _bytes('<c hoi="dag"></c>'),
1952 b)
1953
1954 required_versions_ET['test_iter'] = (1,3)
1956 Element = self.etree.Element
1957 SubElement = self.etree.SubElement
1958
1959 a = Element('a')
1960 b = SubElement(a, 'b')
1961 c = SubElement(a, 'c')
1962 d = SubElement(b, 'd')
1963 e = SubElement(c, 'e')
1964
1965 self.assertEqual(
1966 [a, b, d, c, e],
1967 list(a.iter()))
1968 self.assertEqual(
1969 [d],
1970 list(d.iter()))
1971
1973 Element = self.etree.Element
1974 SubElement = self.etree.SubElement
1975
1976 a = Element('a')
1977 a.text = 'a'
1978 a.tail = 'a1' * 100
1979 b = SubElement(a, 'b')
1980 b.text = 'b'
1981 b.tail = 'b1' * 100
1982 c = SubElement(a, 'c')
1983 c.text = 'c'
1984 c.tail = 'c1' * 100
1985 d = SubElement(b, 'd')
1986 d.text = 'd'
1987 d.tail = 'd1' * 100
1988 e = SubElement(c, 'e')
1989 e.text = 'e'
1990 e.tail = 'e1' * 100
1991
1992 for el in a.iter():
1993 el.tail = None
1994 el = None
1995
1996 self.assertEqual(
1997 [None] * 5,
1998 [el.tail for el in a.iter()])
1999
2001 Element = self.etree.Element
2002 SubElement = self.etree.SubElement
2003
2004 a = Element('a')
2005 b = SubElement(a, 'b')
2006 c = SubElement(a, 'c')
2007 d = SubElement(b, 'd')
2008 e = SubElement(c, 'e')
2009
2010 self.assertEqual(
2011 [a, b, d, c, e],
2012 list(a.getiterator()))
2013 self.assertEqual(
2014 [d],
2015 list(d.getiterator()))
2016
2018 Element = self.etree.Element
2019 SubElement = self.etree.SubElement
2020
2021 a = Element('a')
2022 b = SubElement(a, 'b')
2023 c = SubElement(a, 'c')
2024 d = SubElement(b, 'd')
2025 e = SubElement(c, 'e')
2026
2027 self.assertEqual(
2028 [],
2029 list(a.getiterator('none')))
2030 self.assertEqual(
2031 [],
2032 list(e.getiterator('none')))
2033 self.assertEqual(
2034 [e],
2035 list(e.getiterator()))
2036
2038 Element = self.etree.Element
2039 SubElement = self.etree.SubElement
2040
2041 a = Element('a')
2042 b = SubElement(a, 'b')
2043 c = SubElement(a, 'c')
2044 d = SubElement(b, 'd')
2045 e = SubElement(c, 'e')
2046
2047 self.assertEqual(
2048 [a],
2049 list(a.getiterator('a')))
2050 a2 = SubElement(e, 'a')
2051 self.assertEqual(
2052 [a, a2],
2053 list(a.getiterator('a')))
2054 self.assertEqual(
2055 [a2],
2056 list(c.getiterator('a')))
2057
2059 Element = self.etree.Element
2060 SubElement = self.etree.SubElement
2061
2062 a = Element('a')
2063 b = SubElement(a, 'b')
2064 c = SubElement(a, 'c')
2065 d = SubElement(b, 'd')
2066 e = SubElement(c, 'e')
2067
2068 self.assertEqual(
2069 [a, b, d, c, e],
2070 list(a.getiterator('*')))
2071
2073 Element = self.etree.Element
2074 Comment = self.etree.Comment
2075 SubElement = self.etree.SubElement
2076
2077 a = Element('a')
2078 b = SubElement(a, 'b')
2079 comment_b = Comment("TEST-b")
2080 b.append(comment_b)
2081
2082 self.assertEqual(
2083 [comment_b],
2084 list(a.getiterator(Comment)))
2085
2086 comment_a = Comment("TEST-a")
2087 a.append(comment_a)
2088
2089 self.assertEqual(
2090 [comment_b, comment_a],
2091 list(a.getiterator(Comment)))
2092
2093 self.assertEqual(
2094 [comment_b],
2095 list(b.getiterator(Comment)))
2096
2098 Element = self.etree.Element
2099 PI = self.etree.ProcessingInstruction
2100 SubElement = self.etree.SubElement
2101
2102 a = Element('a')
2103 b = SubElement(a, 'b')
2104 pi_b = PI("TEST-b")
2105 b.append(pi_b)
2106
2107 self.assertEqual(
2108 [pi_b],
2109 list(a.getiterator(PI)))
2110
2111 pi_a = PI("TEST-a")
2112 a.append(pi_a)
2113
2114 self.assertEqual(
2115 [pi_b, pi_a],
2116 list(a.getiterator(PI)))
2117
2118 self.assertEqual(
2119 [pi_b],
2120 list(b.getiterator(PI)))
2121
2123 Element = self.etree.Element
2124 SubElement = self.etree.SubElement
2125
2126 a = Element('a')
2127 a.text = 'a'
2128 b = SubElement(a, 'b')
2129 b.text = 'b'
2130 b.tail = 'b1'
2131 c = SubElement(a, 'c')
2132 c.text = 'c'
2133 c.tail = 'c1'
2134 d = SubElement(b, 'd')
2135 d.text = 'd'
2136 d.tail = 'd1'
2137 e = SubElement(c, 'e')
2138 e.text = 'e'
2139 e.tail = 'e1'
2140
2141 self.assertEqual(
2142 [a, b, d, c, e],
2143 list(a.getiterator()))
2144 #self.assertEqual(
2145 # [d],
2146 # list(d.getiterator()))
2147
2149 Element = self.etree.Element
2150 SubElement = self.etree.SubElement
2151
2152 a = Element('a')
2153 a.text = 'a'
2154 b = SubElement(a, 'b')
2155 b.text = 'b'
2156 b.tail = 'b1'
2157 c = SubElement(a, 'c')
2158 c.text = 'c'
2159 c.tail = 'c1'
2160 d = SubElement(b, 'd')
2161 d.text = 'd'
2162 d.tail = 'd1'
2163 e = SubElement(c, 'e')
2164 e.text = 'e'
2165 e.tail = 'e1'
2166
2167 self.assertEqual(
2168 [a],
2169 list(a.getiterator('a')))
2170 a2 = SubElement(e, 'a')
2171 self.assertEqual(
2172 [a, a2],
2173 list(a.getiterator('a')))
2174 self.assertEqual(
2175 [a2],
2176 list(e.getiterator('a')))
2177
2179 Element = self.etree.Element
2180 SubElement = self.etree.SubElement
2181
2182 a = Element('a')
2183 b = SubElement(a, 'b')
2184 c = SubElement(a, 'c')
2185 d = SubElement(a, 'd')
2186
2187 self.assertEqual(
2188 [b, c],
2189 a[0:2])
2190 self.assertEqual(
2191 [b, c, d],
2192 a[:])
2193 self.assertEqual(
2194 [b, c, d],
2195 a[:10])
2196 self.assertEqual(
2197 [b],
2198 a[0:1])
2199 self.assertEqual(
2200 [],
2201 a[10:12])
2202
2204 Element = self.etree.Element
2205 SubElement = self.etree.SubElement
2206
2207 a = Element('a')
2208 b = SubElement(a, 'b')
2209 c = SubElement(a, 'c')
2210 d = SubElement(a, 'd')
2211
2212 self.assertEqual(
2213 [d],
2214 a[-1:])
2215 self.assertEqual(
2216 [c, d],
2217 a[-2:])
2218 self.assertEqual(
2219 [c],
2220 a[-2:-1])
2221 self.assertEqual(
2222 [b, c],
2223 a[-3:-1])
2224 self.assertEqual(
2225 [b, c],
2226 a[-3:2])
2227
2229 Element = self.etree.Element
2230 SubElement = self.etree.SubElement
2231
2232 a = Element('a')
2233 b = SubElement(a, 'b')
2234 c = SubElement(a, 'c')
2235 d = SubElement(a, 'd')
2236 e = SubElement(a, 'e')
2237
2238 self.assertEqual(
2239 [e,d,c,b],
2240 a[::-1])
2241 self.assertEqual(
2242 [b,d],
2243 a[::2])
2244 self.assertEqual(
2245 [e,c],
2246 a[::-2])
2247 self.assertEqual(
2248 [d,c],
2249 a[-2:0:-1])
2250 self.assertEqual(
2251 [e],
2252 a[:1:-2])
2253
2255 ElementTree = self.etree.ElementTree
2256
2257 f = BytesIO('<a><b>B</b>B1<c>C</c>C1</a>')
2258 doc = ElementTree(file=f)
2259 a = doc.getroot()
2260 b = a[0]
2261 c = a[1]
2262 self.assertEqual(
2263 [b, c],
2264 a[:])
2265 self.assertEqual(
2266 [b],
2267 a[0:1])
2268 self.assertEqual(
2269 [c],
2270 a[1:])
2271
2273 Element = self.etree.Element
2274 Comment = self.etree.Comment
2275 SubElement = self.etree.SubElement
2276
2277 a = Element('a')
2278 b = SubElement(a, 'b')
2279 foo = Comment('foo')
2280 a.append(foo)
2281 c = SubElement(a, 'c')
2282 self.assertEqual(
2283 [b, foo, c],
2284 a[:])
2285 self.assertEqual(
2286 foo,
2287 a[1])
2288 a[1] = new = Element('new')
2289 self.assertEqual(
2290 new,
2291 a[1])
2292 self.assertXML(
2293 _bytes('<a><b></b><new></new><c></c></a>'),
2294 a)
2295
2297 Element = self.etree.Element
2298 SubElement = self.etree.SubElement
2299
2300 a = Element('a')
2301 b = SubElement(a, 'b')
2302 c = SubElement(a, 'c')
2303 d = SubElement(a, 'd')
2304 e = SubElement(a, 'e')
2305
2306 del a[1:3]
2307 self.assertEqual(
2308 [b, e],
2309 list(a))
2310
2312 Element = self.etree.Element
2313 SubElement = self.etree.SubElement
2314
2315 a = Element('a')
2316 b = SubElement(a, 'b')
2317 c = SubElement(a, 'c')
2318 d = SubElement(a, 'd')
2319 e = SubElement(a, 'e')
2320
2321 del a[1:-1]
2322 self.assertEqual(
2323 [b, e],
2324 list(a))
2325
2327 Element = self.etree.Element
2328 SubElement = self.etree.SubElement
2329
2330 a = Element('a')
2331 b = SubElement(a, 'b')
2332 c = SubElement(a, 'c')
2333 d = SubElement(a, 'd')
2334 e = SubElement(a, 'e')
2335
2336 del a[-3:-1]
2337 self.assertEqual(
2338 [b, e],
2339 list(a))
2340
2342 Element = self.etree.Element
2343 SubElement = self.etree.SubElement
2344
2345 a = Element('a')
2346 b = SubElement(a, 'b')
2347 c = SubElement(a, 'c')
2348 d = SubElement(a, 'd')
2349 e = SubElement(a, 'e')
2350
2351 del a[1::2]
2352 self.assertEqual(
2353 [b, d],
2354 list(a))
2355
2357 Element = self.etree.Element
2358 SubElement = self.etree.SubElement
2359
2360 a = Element('a')
2361 b = SubElement(a, 'b')
2362 c = SubElement(a, 'c')
2363 d = SubElement(a, 'd')
2364 e = SubElement(a, 'e')
2365
2366 del a[::-1]
2367 self.assertEqual(
2368 [],
2369 list(a))
2370
2372 Element = self.etree.Element
2373 SubElement = self.etree.SubElement
2374
2375 a = Element('a')
2376 b = SubElement(a, 'b')
2377 c = SubElement(a, 'c')
2378 d = SubElement(a, 'd')
2379 e = SubElement(a, 'e')
2380
2381 del a[::-2]
2382 self.assertEqual(
2383 [b, d],
2384 list(a))
2385
2387 ElementTree = self.etree.ElementTree
2388 f = BytesIO('<a><b></b>B2<c></c>C2<d></d>D2<e></e>E2</a>')
2389 doc = ElementTree(file=f)
2390 a = doc.getroot()
2391 del a[1:3]
2392 self.assertXML(
2393 _bytes('<a><b></b>B2<e></e>E2</a>'),
2394 a)
2395
2397 XML = self.etree.XML
2398 a = XML(_bytes('<a><b></b>B2<c></c>C2</a>'))
2399 b, c = a
2400
2401 del a[:]
2402
2403 self.assertEqual("B2", b.tail)
2404 self.assertEqual("C2", c.tail)
2405
2407 # this could trigger a crash
2408 Element = self.etree.Element
2409 SubElement = self.etree.SubElement
2410 a = Element('a')
2411 b = SubElement(a, 'b')
2412 c = SubElement(b, 'c')
2413 del b # no more reference to b
2414 del a[:]
2415 self.assertEqual('c', c.tag)
2416
2418 Element = self.etree.Element
2419 SubElement = self.etree.SubElement
2420
2421 a = Element('a')
2422 b = SubElement(a, 'b')
2423 c = SubElement(a, 'c')
2424 d = SubElement(a, 'd')
2425
2426 e = Element('e')
2427 f = Element('f')
2428 g = Element('g')
2429
2430 s = [e, f, g]
2431 a[1:2] = s
2432 self.assertEqual(
2433 [b, e, f, g, d],
2434 list(a))
2435
2437 Element = self.etree.Element
2438 SubElement = self.etree.SubElement
2439
2440 a = Element('a')
2441 b = SubElement(a, 'b')
2442 c = SubElement(a, 'c')
2443
2444 e = Element('e')
2445 f = Element('f')
2446 g = Element('g')
2447
2448 s = [e, f, g]
2449 a[:] = s
2450 self.assertEqual(
2451 [e, f, g],
2452 list(a))
2453
2455 Element = self.etree.Element
2456 SubElement = self.etree.SubElement
2457
2458 a = Element('a')
2459
2460 e = Element('e')
2461 f = Element('f')
2462 g = Element('g')
2463
2464 s = [e, f, g]
2465 a[:] = s
2466 self.assertEqual(
2467 [e, f, g],
2468 list(a))
2469
2471 Element = self.etree.Element
2472 SubElement = self.etree.SubElement
2473
2474 a = Element('a')
2475 b = SubElement(a, 'b')
2476 c = SubElement(a, 'c')
2477 d = SubElement(a, 'd')
2478
2479 s = [b, c, d]
2480 a[:] = s
2481 self.assertEqual(
2482 [b, c, d],
2483 list(a))
2484
2486 Element = self.etree.Element
2487 SubElement = self.etree.SubElement
2488
2489 a = Element('a')
2490 b = SubElement(a, 'b')
2491 c = SubElement(a, 'c')
2492 d = SubElement(a, 'd')
2493
2494 s = [d, c, b]
2495 a[:] = s
2496 self.assertEqual(
2497 [d, c, b],
2498 list(a))
2499
2501 Element = self.etree.Element
2502 SubElement = self.etree.SubElement
2503
2504 a = Element('{ns}a')
2505 b = SubElement(a, '{ns}b', {'{ns1}a1': 'test'})
2506 c = SubElement(a, '{ns}c', {'{ns2}a2': 'test'})
2507 d = SubElement(a, '{ns}d', {'{ns3}a3': 'test'})
2508
2509 s = [d, c, b]
2510 a[:] = s
2511 self.assertEqual(
2512 [d, c, b],
2513 list(a))
2514 self.assertEqual(
2515 ['{ns}d', '{ns}c', '{ns}b'],
2516 [ child.tag for child in a ])
2517
2518 self.assertEqual(
2519 [['{ns3}a3'], ['{ns2}a2'], ['{ns1}a1']],
2520 [ list(child.attrib.keys()) for child in a ])
2521
2523 Element = self.etree.Element
2524 SubElement = self.etree.SubElement
2525
2526 a = Element('{ns}a')
2527 b = SubElement(a, '{ns1}b', {'{ns}a1': 'test'})
2528 c = SubElement(a, '{ns2}c', {'{ns}a2': 'test'})
2529 d = SubElement(a, '{ns3}d', {'{ns}a3': 'test'})
2530
2531 s = [d, c, b]
2532 a[:] = s
2533 self.assertEqual(
2534 [d, c, b],
2535 list(a))
2536 self.assertEqual(
2537 ['{ns3}d', '{ns2}c', '{ns1}b'],
2538 [ child.tag for child in a ])
2539
2540 self.assertEqual(
2541 [['{ns}a3'], ['{ns}a2'], ['{ns}a1']],
2542 [ list(child.attrib.keys()) for child in a ])
2543
2545 Element = self.etree.Element
2546 SubElement = self.etree.SubElement
2547
2548 a = Element('a')
2549 b = SubElement(a, 'b')
2550 c = SubElement(a, 'c')
2551
2552 e = Element('e')
2553 f = Element('f')
2554 g = Element('g')
2555 h = Element('h')
2556
2557 s = [e, f]
2558 a[99:] = s
2559 self.assertEqual(
2560 [b, c, e, f],
2561 list(a))
2562
2563 s = [g, h]
2564 a[:0] = s
2565 self.assertEqual(
2566 [g, h, b, c, e, f],
2567 list(a))
2568
2570 Element = self.etree.Element
2571 SubElement = self.etree.SubElement
2572
2573 a = Element('a')
2574 b = SubElement(a, 'b')
2575 c = SubElement(a, 'c')
2576 d = SubElement(a, 'd')
2577
2578 e = Element('e')
2579 f = Element('f')
2580 g = Element('g')
2581
2582 s = [e, f, g]
2583 a[3:] = s
2584 self.assertEqual(
2585 [b, c, d, e, f, g],
2586 list(a))
2587
2589 Element = self.etree.Element
2590 SubElement = self.etree.SubElement
2591
2592 a = Element('a')
2593 b = SubElement(a, 'b')
2594 c = SubElement(a, 'c')
2595
2596 e = Element('e')
2597 f = Element('f')
2598
2599 s = [e]
2600 a[0:1] = s
2601 self.assertEqual(
2602 [e, c],
2603 list(a))
2604
2605 s = [f]
2606 a[1:2] = s
2607 self.assertEqual(
2608 [e, f],
2609 list(a))
2610
2612 ElementTree = self.etree.ElementTree
2613 Element = self.etree.Element
2614 f = BytesIO('<a><b></b>B2<c></c>C2<d></d>D2<e></e>E2</a>')
2615 doc = ElementTree(file=f)
2616 a = doc.getroot()
2617 x = Element('x')
2618 y = Element('y')
2619 z = Element('z')
2620 x.tail = 'X2'
2621 y.tail = 'Y2'
2622 z.tail = 'Z2'
2623 a[1:3] = [x, y, z]
2624 self.assertXML(
2625 _bytes('<a><b></b>B2<x></x>X2<y></y>Y2<z></z>Z2<e></e>E2</a>'),
2626 a)
2627
2629 Element = self.etree.Element
2630 SubElement = self.etree.SubElement
2631
2632 a = Element('a')
2633 b = SubElement(a, 'b')
2634 c = SubElement(a, 'c')
2635 d = SubElement(a, 'd')
2636
2637 x = Element('x')
2638 y = Element('y')
2639
2640 a[1:-1] = [x, y]
2641 self.assertEqual(
2642 [b, x, y, d],
2643 list(a))
2644
2646 Element = self.etree.Element
2647 SubElement = self.etree.SubElement
2648
2649 a = Element('a')
2650 b = SubElement(a, 'b')
2651 c = SubElement(a, 'c')
2652 d = SubElement(a, 'd')
2653
2654 x = Element('x')
2655 y = Element('y')
2656
2657 a[1:-2] = [x, y]
2658 self.assertEqual(
2659 [b, x, y, c, d],
2660 list(a))
2661
2663 Element = self.etree.Element
2664
2665 a = Element('a')
2666
2667 b = Element('b')
2668 c = Element('c')
2669
2670 a[:] = [b, c]
2671 self.assertEqual(
2672 [b, c],
2673 list(a))
2674
2676 Element = self.etree.Element
2677 ElementTree = self.etree.ElementTree
2678
2679 a = Element('a')
2680 a.tail = 'A2'
2681 t = ElementTree(element=a)
2682 self.assertEqual('A2',
2683 a.tail)
2684
2686 Element = self.etree.Element
2687 SubElement = self.etree.SubElement
2688 ElementTree = self.etree.ElementTree
2689
2690 a = Element('a')
2691 b = SubElement(a, 'b')
2692 c = SubElement(a, 'c')
2693 d = SubElement(b, 'd')
2694 e = SubElement(c, 'e')
2695 t = ElementTree(element=a)
2696
2697 self.assertEqual(
2698 [a, b, d, c, e],
2699 list(t.getiterator()))
2700
2702 Element = self.etree.Element
2703 SubElement = self.etree.SubElement
2704 ElementTree = self.etree.ElementTree
2705 a = Element('a')
2706 b = SubElement(a, 'b')
2707 c = SubElement(a, 'c')
2708 d = SubElement(b, 'd')
2709 e = SubElement(c, 'e')
2710 t = ElementTree(element=a)
2711
2712 self.assertEqual(
2713 [a],
2714 list(t.getiterator('a')))
2715 a2 = SubElement(e, 'a')
2716 self.assertEqual(
2717 [a, a2],
2718 list(t.getiterator('a')))
2719
2721 ElementTree = self.etree.ElementTree
2722 ns = 'http://xml.infrae.com/1'
2723 f = BytesIO('<x:a xmlns:x="%s"><x:b></x:b></x:a>' % ns)
2724 t = ElementTree(file=f)
2725 a = t.getroot()
2726 self.assertEqual('{%s}a' % ns,
2727 a.tag)
2728 self.assertEqual('{%s}b' % ns,
2729 a[0].tag)
2730
2732 ElementTree = self.etree.ElementTree
2733 ns = 'http://xml.infrae.com/1'
2734 ns2 = 'http://xml.infrae.com/2'
2735 f = BytesIO('<x:a xmlns:x="%s" xmlns:y="%s"><x:b></x:b><y:b></y:b></x:a>' % (ns, ns2))
2736 t = ElementTree(file=f)
2737 a = t.getroot()
2738 self.assertEqual('{%s}a' % ns,
2739 a.tag)
2740 self.assertEqual('{%s}b' % ns,
2741 a[0].tag)
2742 self.assertEqual('{%s}b' % ns2,
2743 a[1].tag)
2744
2746 Element = self.etree.Element
2747 SubElement = self.etree.SubElement
2748 ns = 'http://xml.infrae.com/1'
2749 ns2 = 'http://xml.infrae.com/2'
2750 a = Element('{%s}a' % ns)
2751 b = SubElement(a, '{%s}b' % ns2)
2752 c = SubElement(a, '{%s}c' % ns)
2753 self.assertEqual('{%s}a' % ns,
2754 a.tag)
2755 self.assertEqual('{%s}b' % ns2,
2756 b.tag)
2757 self.assertEqual('{%s}c' % ns,
2758 c.tag)
2759 self.assertEqual('{%s}a' % ns,
2760 a.tag)
2761 self.assertEqual('{%s}b' % ns2,
2762 b.tag)
2763 self.assertEqual('{%s}c' % ns,
2764 c.tag)
2765
2767 Element = self.etree.Element
2768 SubElement = self.etree.SubElement
2769 ElementTree = self.etree.ElementTree
2770
2771 ns = 'http://xml.infrae.com/1'
2772 ns2 = 'http://xml.infrae.com/2'
2773 f = BytesIO('<a xmlns="%s" xmlns:x="%s"><x:b></x:b><b></b></a>' % (ns, ns2))
2774 t = ElementTree(file=f)
2775
2776 a = t.getroot()
2777 self.assertEqual('{%s}a' % ns,
2778 a.tag)
2779 self.assertEqual('{%s}b' % ns2,
2780 a[0].tag)
2781 self.assertEqual('{%s}b' % ns,
2782 a[1].tag)
2783
2785 Element = self.etree.Element
2786 ns = 'http://xml.infrae.com/1'
2787 ns2 = 'http://xml.infrae.com/2'
2788 a = Element('a')
2789 a.set('{%s}foo' % ns, 'Foo')
2790 a.set('{%s}bar' % ns2, 'Bar')
2791 self.assertEqual(
2792 'Foo',
2793 a.get('{%s}foo' % ns))
2794 self.assertEqual(
2795 'Bar',
2796 a.get('{%s}bar' % ns2))
2797 try:
2798 self.assertXML(
2799 _bytes('<a xmlns:ns0="%s" xmlns:ns1="%s" ns0:foo="Foo" ns1:bar="Bar"></a>' % (ns, ns2)),
2800 a)
2801 except AssertionError:
2802 self.assertXML(
2803 _bytes('<a xmlns:ns0="%s" xmlns:ns1="%s" ns1:foo="Foo" ns0:bar="Bar"></a>' % (ns2, ns)),
2804 a)
2805
2807 Element = self.etree.Element
2808 one = self.etree.fromstring(
2809 _bytes('<foo><bar xmlns:ns="http://a.b.c"><ns:baz/></bar></foo>'))
2810 baz = one[0][0]
2811
2812 two = Element('root')
2813 two.append(baz)
2814 # removing the originating document could cause a crash/error before
2815 # as namespace is not moved along with it
2816 del one, baz
2817 self.assertEqual('{http://a.b.c}baz', two[0].tag)
2818
2820 tostring = self.etree.tostring
2821 root = self.etree.XML(
2822 _bytes('<foo><bar xmlns:ns="http://a.b.c"><ns:baz/></bar></foo>'))
2823 baz = root[0][0]
2824
2825 nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
2826 tostring(baz))
2827 self.assertEqual([_bytes("http://a.b.c")], nsdecl)
2828
2830 tostring = self.etree.tostring
2831 root = self.etree.XML(
2832 _bytes('<foo><bar xmlns="http://a.b.c"><baz/></bar></foo>'))
2833 baz = root[0][0]
2834
2835 nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
2836 tostring(baz))
2837 self.assertEqual([_bytes("http://a.b.c")], nsdecl)
2838
2840 tostring = self.etree.tostring
2841 root = self.etree.XML(
2842 _bytes('<foo xmlns:ns="http://a.b.c"><bar><ns:baz/></bar></foo>'))
2843 baz = root[0][0]
2844
2845 nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
2846 tostring(baz))
2847
2848 self.assertEqual([_bytes("http://a.b.c")], nsdecl)
2849
2851 Element = self.etree.Element
2852 SubElement = self.etree.SubElement
2853
2854 root = Element("foo")
2855 bar = SubElement(root, "{http://a.b.c}bar")
2856 baz = SubElement(bar, "{http://a.b.c}baz")
2857
2858 nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
2859 self.etree.tostring(baz))
2860
2861 self.assertEqual([_bytes("http://a.b.c")], nsdecl)
2862
2864 Element = self.etree.Element
2865
2866 root = Element('element')
2867
2868 subelement = Element('subelement',
2869 {"{http://www.w3.org/XML/1998/namespace}id": "foo"})
2870 self.assertEqual(1, len(subelement.attrib))
2871 self.assertEqual(
2872 "foo",
2873 subelement.get("{http://www.w3.org/XML/1998/namespace}id"))
2874
2875 root.append(subelement)
2876 self.assertEqual(1, len(subelement.attrib))
2877 self.assertEqual(
2878 list({"{http://www.w3.org/XML/1998/namespace}id" : "foo"}.items()),
2879 list(subelement.attrib.items()))
2880 self.assertEqual(
2881 "foo",
2882 subelement.get("{http://www.w3.org/XML/1998/namespace}id"))
2883
2885 parse = self.etree.parse
2886 tostring = self.etree.tostring
2887
2888 ns_href = "http://a.b.c"
2889 one = parse(
2890 BytesIO('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2891 baz = one.getroot()[0][0]
2892
2893 parsed = parse(BytesIO( tostring(baz) )).getroot()
2894 self.assertEqual('{%s}baz' % ns_href, parsed.tag)
2895
2897 fromstring = self.etree.fromstring
2898 tostring = self.etree.tostring
2899
2900 ns_href = "http://a.b.c"
2901 xml = _bytes('<root xmlns="%s" xmlns:x="%s"><el x:a="test" /></root>' % (
2902 ns_href,ns_href))
2903 root = fromstring(xml)
2904 self.assertEqual('test', root[0].get('{%s}a' % ns_href))
2905
2906 xml2 = tostring(root)
2907 self.assertTrue(_bytes(':a=') in xml2, xml2)
2908
2909 root2 = fromstring(xml2)
2910 self.assertEqual('test', root2[0].get('{%s}a' % ns_href))
2911
2913 fromstring = self.etree.fromstring
2914 tostring = self.etree.tostring
2915
2916 ns_href = "http://a.b.c"
2917 xml = _bytes('<root xmlns="%s" xmlns:x="%s"><el x:a="test" /></root>' % (
2918 ns_href,ns_href))
2919 root = fromstring(xml)
2920 self.assertEqual('test', root[0].get('{%s}a' % ns_href))
2921
2922 root[0].set('{%s}a' % ns_href, 'TEST')
2923
2924 xml2 = tostring(root)
2925 self.assertTrue(_bytes(':a=') in xml2, xml2)
2926
2927 root2 = fromstring(xml2)
2928 self.assertEqual('TEST', root2[0].get('{%s}a' % ns_href))
2929
2930 required_versions_ET['test_register_namespace'] = (1,3)
2932 # ET 1.3+
2933 Element = self.etree.Element
2934 prefix = 'TESTPREFIX'
2935 namespace = 'http://seriously.unknown/namespace/URI'
2936
2937 el = Element('{%s}test' % namespace)
2938 self.assertEqual(_bytes('<ns0:test xmlns:ns0="%s"></ns0:test>' % namespace),
2939 self._writeElement(el))
2940
2941 self.etree.register_namespace(prefix, namespace)
2942 el = Element('{%s}test' % namespace)
2943 self.assertEqual(_bytes('<%s:test xmlns:%s="%s"></%s:test>' % (
2944 prefix, prefix, namespace, prefix)),
2945 self._writeElement(el))
2946
2947 self.assertRaises(ValueError, self.etree.register_namespace, 'ns25', namespace)
2948
2950 tostring = self.etree.tostring
2951 Element = self.etree.Element
2952 SubElement = self.etree.SubElement
2953
2954 a = Element('a')
2955 b = SubElement(a, 'b')
2956 c = SubElement(a, 'c')
2957
2958 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
2959 canonicalize(tostring(a)))
2960
2962 tostring = self.etree.tostring
2963 Element = self.etree.Element
2964 SubElement = self.etree.SubElement
2965
2966 a = Element('a')
2967 b = SubElement(a, 'b')
2968 c = SubElement(a, 'c')
2969 d = SubElement(c, 'd')
2970 self.assertEqual(_bytes('<b></b>'),
2971 canonicalize(tostring(b)))
2972 self.assertEqual(_bytes('<c><d></d></c>'),
2973 canonicalize(tostring(c)))
2974
2976 tostring = self.etree.tostring
2977 Element = self.etree.Element
2978 SubElement = self.etree.SubElement
2979
2980 a = Element('a')
2981 b = SubElement(a, 'b')
2982 c = SubElement(a, 'c')
2983 d = SubElement(c, 'd')
2984 b.tail = 'Foo'
2985
2986 self.assertTrue(tostring(b) == _bytes('<b/>Foo') or
2987 tostring(b) == _bytes('<b />Foo'))
2988
2989 required_versions_ET['test_tostring_method_html'] = (1,3)
2991 tostring = self.etree.tostring
2992 Element = self.etree.Element
2993 SubElement = self.etree.SubElement
2994
2995 html = Element('html')
2996 body = SubElement(html, 'body')
2997 p = SubElement(body, 'p')
2998 p.text = "html"
2999 SubElement(p, 'br').tail = "test"
3000
3001 self.assertEqual(_bytes('<html><body><p>html<br>test</p></body></html>'),
3002 tostring(html, method="html"))
3003
3004 required_versions_ET['test_tostring_method_text'] = (1,3)
3006 tostring = self.etree.tostring
3007 Element = self.etree.Element
3008 SubElement = self.etree.SubElement
3009
3010 a = Element('a')
3011 a.text = "A"
3012 a.tail = "tail"
3013 b = SubElement(a, 'b')
3014 b.text = "B"
3015 b.tail = "TAIL"
3016 c = SubElement(a, 'c')
3017 c.text = "C"
3018
3019 self.assertEqual(_bytes('ABTAILCtail'),
3020 tostring(a, method="text"))
3021
3023 iterparse = self.etree.iterparse
3024 f = BytesIO('<a><b></b><c/></a>')
3025
3026 iterator = iterparse(f)
3027 self.assertEqual(None,
3028 iterator.root)
3029 events = list(iterator)
3030 root = iterator.root
3031 self.assertEqual(
3032 [('end', root[0]), ('end', root[1]), ('end', root)],
3033 events)
3034
3036 iterparse = self.etree.iterparse
3037 f = BytesIO('<a><b></b><c/></a>')
3038
3039 iterator = iterparse(f)
3040 self.assertEqual(None,
3041 iterator.root)
3042 event, element = next(iter(iterator))
3043 self.assertEqual('end', event)
3044 self.assertEqual('b', element.tag)
3045
3047 iterparse = self.etree.iterparse
3048 iterator = iterparse(fileInTestDir("test.xml"))
3049 self.assertEqual(None,
3050 iterator.root)
3051 events = list(iterator)
3052 root = iterator.root
3053 self.assertEqual(
3054 [('end', root[0]), ('end', root)],
3055 events)
3056
3058 iterparse = self.etree.iterparse
3059 f = BytesIO('<a><b></b><c/></a>')
3060
3061 iterator = iterparse(f, events=('start',))
3062 events = list(iterator)
3063 root = iterator.root
3064 self.assertEqual(
3065 [('start', root), ('start', root[0]), ('start', root[1])],
3066 events)
3067
3069 iterparse = self.etree.iterparse
3070 f = BytesIO('<a><b></b><c/></a>')
3071
3072 iterator = iterparse(f, events=('start','end'))
3073 events = list(iterator)
3074 root = iterator.root
3075 self.assertEqual(
3076 [('start', root), ('start', root[0]), ('end', root[0]),
3077 ('start', root[1]), ('end', root[1]), ('end', root)],
3078 events)
3079
3081 iterparse = self.etree.iterparse
3082 f = BytesIO('<a><b></b><c/></a>')
3083
3084 iterator = iterparse(f)
3085 for event, elem in iterator:
3086 elem.clear()
3087
3088 root = iterator.root
3089 self.assertEqual(0,
3090 len(root))
3091
3093 iterparse = self.etree.iterparse
3094 CHILD_COUNT = 12345
3095 f = BytesIO('<a>%s</a>' % ('<b>test</b>'*CHILD_COUNT))
3096
3097 i = 0
3098 for key in iterparse(f):
3099 event, element = key
3100 i += 1
3101 self.assertEqual(i, CHILD_COUNT + 1)
3102
3104 iterparse = self.etree.iterparse
3105 f = BytesIO('<a xmlns="http://ns1/"><b><c xmlns="http://ns2/"/></b></a>')
3106
3107 attr_name = '{http://testns/}bla'
3108 events = []
3109 iterator = iterparse(f, events=('start','end','start-ns','end-ns'))
3110 for event, elem in iterator:
3111 events.append(event)
3112 if event == 'start':
3113 if elem.tag != '{http://ns1/}a':
3114 elem.set(attr_name, 'value')
3115
3116 self.assertEqual(
3117 ['start-ns', 'start', 'start', 'start-ns', 'start',
3118 'end', 'end-ns', 'end', 'end', 'end-ns'],
3119 events)
3120
3121 root = iterator.root
3122 self.assertEqual(
3123 None,
3124 root.get(attr_name))
3125 self.assertEqual(
3126 'value',
3127 root[0].get(attr_name))
3128
3130 iterparse = self.etree.iterparse
3131 f = BytesIO('<a xmlns="http://ns1/"><b><c xmlns="http://ns2/"/></b></a>')
3132
3133 attr_name = '{http://testns/}bla'
3134 events = []
3135 iterator = iterparse(f, events=('start','end','start-ns','end-ns'))
3136 for event, elem in iterator:
3137 events.append(event)
3138 if event == 'start':
3139 if elem.tag != '{http://ns1/}a':
3140 elem.set(attr_name, 'value')
3141
3142 self.assertEqual(
3143 ['start-ns', 'start', 'start', 'start-ns', 'start',
3144 'end', 'end-ns', 'end', 'end', 'end-ns'],
3145 events)
3146
3147 root = iterator.root
3148 self.assertEqual(
3149 None,
3150 root.get(attr_name))
3151 self.assertEqual(
3152 'value',
3153 root[0].get(attr_name))
3154
3156 iterparse = self.etree.iterparse
3157 f = BytesIO('<a><b><d/></b><c/></a>')
3158
3159 counts = []
3160 for event, elem in iterparse(f):
3161 counts.append(len(list(elem.getiterator())))
3162 self.assertEqual(
3163 [1,2,1,4],
3164 counts)
3165
3167 iterparse = self.etree.iterparse
3168 f = BytesIO('<a><b><d/></b><c/></a>')
3169
3170 for event, node in etree.iterparse(f): pass
3171
3172 root = etree.Element('new_root', {})
3173 root[:] = node[:]
3174
3175 self.assertEqual(
3176 ['b', 'c'],
3177 [ el.tag for el in root ])
3178
3180 tostring = self.etree.tostring
3181 f = BytesIO('<root><![CDATA[test]]></root>')
3182 context = self.etree.iterparse(f)
3183 content = [ el.text for event,el in context ]
3184
3185 self.assertEqual(['test'], content)
3186 self.assertEqual(_bytes('<root>test</root>'),
3187 tostring(context.root))
3188
3190 parse = self.etree.parse
3191 # from file
3192 tree = parse(fileInTestDir('test.xml'))
3193 self.assertXML(
3194 _bytes('<a><b></b></a>'),
3195 tree.getroot())
3196
3200
3204
3205 required_versions_ET['test_parse_error'] = (1,3)
3207 # ET < 1.3 raises ExpatError
3208 parse = self.etree.parse
3209 f = BytesIO('<a><b></c></b></a>')
3210 self.assertRaises(SyntaxError, parse, f)
3211 f.close()
3212
3213 required_versions_ET['test_parse_error_from_file'] = (1,3)
3215 parse = self.etree.parse
3216 # from file
3217 f = open(fileInTestDir('test_broken.xml'), 'rb')
3218 self.assertRaises(SyntaxError, parse, f)
3219 f.close()
3220
3222 parse = self.etree.parse
3223 # from file object
3224 f = open(fileInTestDir('test.xml'), 'rb')
3225 tree = parse(f)
3226 f.close()
3227 self.assertXML(
3228 _bytes('<a><b></b></a>'),
3229 tree.getroot())
3230
3232 parse = self.etree.parse
3233 f = BytesIO('<a><b></b></a>')
3234 tree = parse(f)
3235 f.close()
3236 self.assertXML(
3237 _bytes('<a><b></b></a>'),
3238 tree.getroot()
3239 )
3240
3242 tostring = self.etree.tostring
3243 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'))
3244
3245 self.assertEqual('test', root.text)
3246 self.assertEqual(_bytes('<root>test</root>'),
3247 tostring(root))
3248
3250 # this can fail in libxml2 <= 2.6.22
3251 parse = self.etree.parse
3252 tree = parse(BytesIO('<?xml version="1.0" encoding="ascii"?><html/>'))
3253 self.assertXML(_bytes('<html></html>'),
3254 tree.getroot())
3255
3257 Element = self.etree.Element
3258
3259 a = Element('a')
3260 a.text = _str('Søk på nettet')
3261 self.assertXML(
3262 _str('<a>Søk på nettet</a>').encode('UTF-8'),
3263 a, 'utf-8')
3264
3266 ElementTree = self.etree.ElementTree
3267 Element = self.etree.Element
3268
3269 a = Element('a')
3270 a.text = _str('Søk på nettet')
3271
3272 f = BytesIO()
3273 tree = ElementTree(element=a)
3274 tree.write(f, encoding='utf-8')
3275 self.assertEqual(_str('<a>Søk på nettet</a>').encode('UTF-8'),
3276 f.getvalue().replace(_bytes('\n'),_bytes('')))
3277
3279 parse = self.etree.parse
3280 # from file
3281 tree = parse(fileInTestDir('test-string.xml'))
3282 self.assertXML(
3283 _str('<a>Søk på nettet</a>').encode('UTF-8'),
3284 tree.getroot(), 'UTF-8')
3285
3287 parse = self.etree.parse
3288 # from file object
3289 f = open(fileInTestDir('test-string.xml'), 'rb')
3290 tree = parse(f)
3291 f.close()
3292 self.assertXML(
3293 _str('<a>Søk på nettet</a>').encode('UTF-8'),
3294 tree.getroot(), 'UTF-8')
3295
3297 ElementTree = self.etree.ElementTree
3298 Element = self.etree.Element
3299
3300 a = Element('a')
3301 a.text = _str('Søk på nettet')
3302
3303 f = BytesIO()
3304 tree = ElementTree(element=a)
3305 tree.write(f, encoding='iso-8859-1')
3306 result = f.getvalue()
3307 declaration = _bytes("<?xml version=\'1.0\' encoding=\'iso-8859-1\'?>")
3308 self.assertEncodingDeclaration(result, _bytes('iso-8859-1'))
3309 result = result.split(_bytes('?>'), 1)[-1].replace(_bytes('\n'),_bytes(''))
3310 self.assertEqual(_str('<a>Søk på nettet</a>').encode('iso-8859-1'),
3311 result)
3312
3313 required_versions_ET['test_parse_encoding_8bit_explicit'] = (1,3)
3315 XMLParser = self.XMLParser
3316
3317 text = _str('Søk på nettet')
3318 xml_latin1 = (_str('<a>%s</a>') % text).encode('iso-8859-1')
3319
3320 self.assertRaises(self.etree.ParseError,
3321 self.etree.parse,
3322 BytesIO(xml_latin1))
3323
3324 tree = self.etree.parse(BytesIO(xml_latin1),
3325 XMLParser(encoding="iso-8859-1"))
3326 a = tree.getroot()
3327 self.assertEqual(a.text, text)
3328
3329 required_versions_ET['test_parse_encoding_8bit_override'] = (1,3)
3331 XMLParser = self.XMLParser
3332
3333 text = _str('Søk på nettet')
3334 wrong_declaration = _str("<?xml version='1.0' encoding='UTF-8'?>")
3335 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
3336 ).encode('iso-8859-1')
3337
3338 self.assertRaises(self.etree.ParseError,
3339 self.etree.parse,
3340 BytesIO(xml_latin1))
3341
3342 tree = self.etree.parse(BytesIO(xml_latin1),
3343 XMLParser(encoding="iso-8859-1"))
3344 a = tree.getroot()
3345 self.assertEqual(a.text, text)
3346
3348 # raise error on wrong encoding declaration in unicode strings
3349 XML = self.etree.XML
3350 test_utf = (_str('<?xml version="1.0" encoding="iso-8859-1"?>') +
3351 _str('<a>Søk på nettet</a>'))
3352 self.assertRaises(SyntaxError, XML, test_utf)
3353
3355 ElementTree = self.etree.ElementTree
3356 Element = self.etree.Element
3357
3358 a = Element('a')
3359 a.text = _str('Søk på nettet')
3360
3361 f = BytesIO()
3362 tree = ElementTree(element=a)
3363 tree.write(f)
3364 data = f.getvalue().replace(_bytes('\n'),_bytes(''))
3365 self.assertEqual(
3366 _str('<a>Søk på nettet</a>').encode('ASCII', 'xmlcharrefreplace'),
3367 data)
3368
3370 Element = self.etree.Element
3371 tostring = self.etree.tostring
3372
3373 a = Element('a')
3374 a.text = _str('Søk på nettet')
3375 self.assertEqual(_str('<a>Søk på nettet</a>').encode('UTF-8'),
3376 tostring(a, encoding='utf-8'))
3377
3379 Element = self.etree.Element
3380 tostring = self.etree.tostring
3381
3382 a = Element('a')
3383 a.text = _str('Søk på nettet')
3384 self.assertRaises(LookupError, tostring, a,
3385 encoding='Invalid Encoding')
3386
3388 Element = self.etree.Element
3389 SubElement = self.etree.SubElement
3390 tostring = self.etree.tostring
3391
3392 a = Element('a')
3393 b = SubElement(a, 'b')
3394 b.text = _str('Søk på nettet')
3395 self.assertEqual(_str('<b>Søk på nettet</b>').encode('UTF-8'),
3396 tostring(b, encoding='utf-8'))
3397
3399 Element = self.etree.Element
3400 SubElement = self.etree.SubElement
3401 tostring = self.etree.tostring
3402
3403 a = Element('a')
3404 b = SubElement(a, 'b')
3405 b.text = _str('Søk på nettet')
3406 b.tail = _str('Søk')
3407 self.assertEqual(_str('<b>Søk på nettet</b>Søk').encode('UTF-8'),
3408 tostring(b, encoding='utf-8'))
3409
3411 Element = self.etree.Element
3412 SubElement = self.etree.SubElement
3413 tostring = self.etree.tostring
3414
3415 a = Element('a')
3416 a.text = _str('Søk på nettet')
3417
3418 expected = _bytes('<a>Søk på nettet</a>')
3419 self.assertEqual(
3420 expected,
3421 tostring(a))
3422
3424 Element = self.etree.Element
3425 SubElement = self.etree.SubElement
3426 tostring = self.etree.tostring
3427
3428 a = Element('a')
3429 b = SubElement(a, 'b')
3430 b.text = _str('Søk på nettet')
3431
3432 expected = _bytes('<b>Søk på nettet</b>')
3433 self.assertEqual(
3434 expected,
3435 tostring(b))
3436
3438 utext = _str('Søk på nettet')
3439 uxml = _str('<p>%s</p>') % utext
3440 prologue = _bytes('<?xml version="1.0" encoding="iso-8859-1" ?>')
3441 isoxml = prologue + uxml.encode('iso-8859-1')
3442 tree = self.etree.XML(isoxml)
3443 self.assertEqual(utext, tree.text)
3444
3446 utext = _str('Søk på nettet')
3447 uxml = (_str('<?xml version="1.0" encoding="UTF-8"?>') +
3448 _str('<p>%s</p>') % utext)
3449 bom = _bytes('\\xEF\\xBB\\xBF').decode("unicode_escape").encode("latin1")
3450 xml = bom + uxml.encode("utf-8")
3451 tree = etree.XML(xml)
3452 self.assertEqual(utext, tree.text)
3453
3455 utext = _str('Søk på nettet')
3456 uxml = _str('<p>%s</p>') % utext
3457 prologue = _bytes('<?xml version="1.0" encoding="iso-8859-1" ?>')
3458 isoxml = prologue + uxml.encode('iso-8859-1')
3459 el = self.etree.parse(BytesIO(isoxml)).getroot()
3460 self.assertEqual(utext, el.text)
3461
3463 Element = self.etree.Element
3464 ElementTree = self.etree.ElementTree
3465
3466 a = Element('a')
3467 a.text = "Foo"
3468 atree = ElementTree(a)
3469
3470 btree = copy.deepcopy(atree)
3471 self.assertEqual("Foo", atree.getroot().text)
3472 self.assertEqual("Foo", btree.getroot().text)
3473 self.assertFalse(btree is atree)
3474 self.assertFalse(btree.getroot() is atree.getroot())
3475
3477 Element = self.etree.Element
3478
3479 a = Element('a')
3480 a.text = 'Foo'
3481
3482 b = copy.deepcopy(a)
3483 self.assertEqual('Foo', b.text)
3484
3485 b.text = 'Bar'
3486 self.assertEqual('Bar', b.text)
3487 self.assertEqual('Foo', a.text)
3488
3489 del a
3490 self.assertEqual('Bar', b.text)
3491
3493 Element = self.etree.Element
3494
3495 a = Element('a')
3496 a.tail = 'Foo'
3497
3498 b = copy.deepcopy(a)
3499 self.assertEqual('Foo', b.tail)
3500
3501 b.tail = 'Bar'
3502 self.assertEqual('Bar', b.tail)
3503 self.assertEqual('Foo', a.tail)
3504
3505 del a
3506 self.assertEqual('Bar', b.tail)
3507
3509 Element = self.etree.Element
3510 SubElement = self.etree.SubElement
3511
3512 root = Element('root')
3513 a = SubElement(root, 'a')
3514 a.text = 'FooText'
3515 a.tail = 'FooTail'
3516
3517 b = copy.deepcopy(a)
3518 self.assertEqual('FooText', b.text)
3519 self.assertEqual('FooTail', b.tail)
3520
3521 b.text = 'BarText'
3522 b.tail = 'BarTail'
3523 self.assertEqual('BarTail', b.tail)
3524 self.assertEqual('FooTail', a.tail)
3525 self.assertEqual('BarText', b.text)
3526 self.assertEqual('FooText', a.text)
3527
3528 del a
3529 self.assertEqual('BarTail', b.tail)
3530 self.assertEqual('BarText', b.text)
3531
3533 root = self.etree.XML(_bytes('''<doc xmlns="dns" xmlns:t="tns">
3534 <parent><node t:foo="bar" /></parent>
3535 </doc>'''))
3536 self.assertEqual(
3537 root[0][0].get('{tns}foo'),
3538 copy.deepcopy(root[0])[0].get('{tns}foo') )
3539 self.assertEqual(
3540 root[0][0].get('{tns}foo'),
3541 copy.deepcopy(root[0][0]).get('{tns}foo') )
3542
3544 # previously caused a crash
3545 Element = self.etree.Element
3546 tostring = self.etree.tostring
3547
3548 a = Element('a')
3549 b = copy.deepcopy(a)
3550 a.append( Element('C') )
3551 b.append( Element('X') )
3552
3553 self.assertEqual(_bytes('<a><C/></a>'),
3554 tostring(a).replace(_bytes(' '), _bytes('')))
3555 self.assertEqual(_bytes('<a><X/></a>'),
3556 tostring(b).replace(_bytes(' '), _bytes('')))
3557
3559 # previously caused a crash
3560 # not supported by ET < 1.3!
3561 Comment = self.etree.Comment
3562
3563 a = Comment("ONE")
3564 b = copy.deepcopy(a)
3565 b.text = "ANOTHER"
3566
3567 self.assertEqual('ONE', a.text)
3568 self.assertEqual('ANOTHER', b.text)
3569
3571 Element = self.etree.Element
3572
3573 a = Element('a')
3574 a.text = 'Foo'
3575
3576 b = copy.copy(a)
3577 self.assertEqual('Foo', b.text)
3578
3579 b.text = 'Bar'
3580 self.assertEqual('Bar', b.text)
3581 self.assertEqual('Foo', a.text)
3582 # XXX ElementTree will share nodes, but lxml.etree won't..
3583
3585 Element = self.etree.Element
3586 ElementTree = self.etree.ElementTree
3587
3588 a = Element('a')
3589 a.text = 'Foo'
3590 atree = ElementTree(a)
3591
3592 btree = copy.copy(atree)
3593 self.assertFalse(btree is atree)
3594 self.assertTrue(btree.getroot() is atree.getroot())
3595 self.assertEqual('Foo', atree.getroot().text)
3596
3598 # deprecated as of ET 1.3/lxml 2.0
3599 etree = self.etree
3600 e = etree.Element('foo')
3601 self.assertEqual(False, bool(e))
3602 etree.SubElement(e, 'bar')
3603 self.assertEqual(True, bool(e))
3604 e = etree.Element('foo')
3605 e.text = 'hey'
3606 self.assertEqual(False, bool(e))
3607 e = etree.Element('foo')
3608 e.tail = 'bar'
3609 self.assertEqual(False, bool(e))
3610 e = etree.Element('foo')
3611 e.set('bar', 'Bar')
3612 self.assertEqual(False, bool(e))
3613
3615 etree = self.etree
3616
3617 a = etree.Element('a')
3618 b = etree.SubElement(a, 'b')
3619
3620 t = etree.ElementTree(a)
3621 self.assertEqual(self._rootstring(t), _bytes('<a><b/></a>'))
3622
3623 t1 = etree.ElementTree(a)
3624 self.assertEqual(self._rootstring(t1), _bytes('<a><b/></a>'))
3625 self.assertEqual(self._rootstring(t), _bytes('<a><b/></a>'))
3626
3627 t2 = etree.ElementTree(b)
3628 self.assertEqual(self._rootstring(t2), _bytes('<b/>'))
3629 self.assertEqual(self._rootstring(t1), _bytes('<a><b/></a>'))
3630 self.assertEqual(self._rootstring(t), _bytes('<a><b/></a>'))
3631
3633 etree = self.etree
3634 qname = etree.QName('myns', 'a')
3635 a1 = etree.Element(qname)
3636 a2 = etree.SubElement(a1, qname)
3637 self.assertEqual(a1.tag, "{myns}a")
3638 self.assertEqual(a2.tag, "{myns}a")
3639
3641 etree = self.etree
3642 qname1 = etree.QName('myns', 'a')
3643 qname2 = etree.QName('myns', 'a')
3644 self.assertEqual(qname1, "{myns}a")
3645 self.assertEqual("{myns}a", qname2)
3646 self.assertEqual(qname1, qname1)
3647 self.assertEqual(qname1, qname2)
3648
3650 etree = self.etree
3651 qname = etree.QName('myns', 'a')
3652
3653 a = etree.Element(qname)
3654 a.set(qname, "value")
3655
3656 self.assertEqual(a.get(qname), "value")
3657 self.assertEqual(a.get("{myns}a"), "value")
3658
3660 etree = self.etree
3661 qname = etree.QName('myns', 'a')
3662
3663 a = etree.Element(qname)
3664 a.attrib[qname] = "value"
3665
3666 self.assertEqual(a.attrib[qname], "value")
3667 self.assertEqual(a.attrib.get(qname), "value")
3668
3669 self.assertEqual(a.attrib["{myns}a"], "value")
3670 self.assertEqual(a.attrib.get("{myns}a"), "value")
3671
3673 etree = self.etree
3674 qname = etree.QName('http://myns', 'a')
3675 a = etree.Element(qname)
3676 a.set(qname, qname)
3677
3678 self.assertXML(
3679 _bytes('<ns0:a xmlns:ns0="http://myns" ns0:a="ns0:a"></ns0:a>'),
3680 a)
3681
3683 etree = self.etree
3684 qname = etree.QName('http://myns', 'a')
3685 a = etree.Element('a')
3686 a.set('a', qname)
3687
3688 self.assertXML(
3689 _bytes('<a xmlns:ns0="http://myns" a="ns0:a"></a>'),
3690 a)
3691
3693 etree = self.etree
3694 qname = etree.QName('http://myns', 'a')
3695 a = etree.Element(qname)
3696 a.attrib[qname] = qname
3697
3698 self.assertXML(
3699 _bytes('<ns0:a xmlns:ns0="http://myns" ns0:a="ns0:a"></ns0:a>'),
3700 a)
3701
3703 etree = self.etree
3704 parser = etree.XMLParser()
3705 if hasattr(parser, "version"):
3706 # ElementTree 1.3+, cET
3707 self.assertTrue(re.match("[^ ]+ [0-9.]+", parser.version))
3708
3709 # feed parser interface
3710
3712 parser = self.XMLParser()
3713
3714 parser.feed(_bytes('<?xml version='))
3715 parser.feed(_bytes('"1.0"?><ro'))
3716 parser.feed(_bytes('ot><'))
3717 parser.feed(_bytes('a test="works"/'))
3718 parser.feed(_bytes('></root'))
3719 parser.feed(_bytes('>'))
3720
3721 root = parser.close()
3722
3723 self.assertEqual(root.tag, "root")
3724 self.assertEqual(root[0].tag, "a")
3725 self.assertEqual(root[0].get("test"), "works")
3726
3728 parser = self.XMLParser()
3729
3730 parser.feed(_str('<ro'))
3731 parser.feed(_str('ot><'))
3732 parser.feed(_str('a test="works"/'))
3733 parser.feed(_str('></root'))
3734 parser.feed(_str('>'))
3735
3736 root = parser.close()
3737
3738 self.assertEqual(root.tag, "root")
3739 self.assertEqual(root[0].tag, "a")
3740 self.assertEqual(root[0].get("test"), "works")
3741
3742 required_versions_ET['test_feed_parser_error_close_empty'] = (1,3)
3744 ParseError = self.etree.ParseError
3745 parser = self.XMLParser()
3746 self.assertRaises(ParseError, parser.close)
3747
3748 required_versions_ET['test_feed_parser_error_close_incomplete'] = (1,3)
3750 ParseError = self.etree.ParseError
3751 parser = self.XMLParser()
3752
3753 parser.feed('<?xml version=')
3754 parser.feed('"1.0"?><ro')
3755
3756 self.assertRaises(ParseError, parser.close)
3757
3758 required_versions_ET['test_feed_parser_error_broken'] = (1,3)
3760 ParseError = self.etree.ParseError
3761 parser = self.XMLParser()
3762
3763 parser.feed('<?xml version=')
3764 parser.feed('"1.0"?><ro')
3765 try:
3766 parser.feed('<><><><><><><')
3767 except ParseError:
3768 # can raise, but not required before close()
3769 pass
3770
3771 self.assertRaises(ParseError, parser.close)
3772
3773 required_versions_ET['test_feed_parser_error_position'] = (1,3)
3775 ParseError = self.etree.ParseError
3776 parser = self.XMLParser()
3777 try:
3778 parser.close()
3779 except ParseError:
3780 e = sys.exc_info()[1]
3781 self.assertNotEqual(None, e.code)
3782 self.assertNotEqual(0, e.code)
3783 self.assertTrue(isinstance(e.position, tuple))
3784 self.assertTrue(e.position >= (0, 0))
3785
3786 # parser target interface
3787
3788 required_versions_ET['test_parser_target_property'] = (1,3)
3792
3793 target = Target()
3794 parser = self.XMLParser(target=target)
3795
3796 self.assertEqual(target, parser.target)
3797
3799 assertEqual = self.assertEqual
3800 assertFalse = self.assertFalse
3801
3802 events = []
3803 class Target(object):
3804 def start(self, tag, attrib):
3805 events.append("start")
3806 assertFalse(attrib)
3807 assertEqual("TAG", tag)
3808 def end(self, tag):
3809 events.append("end")
3810 assertEqual("TAG", tag)
3811 def close(self):
3812 return "DONE"
3813
3814 parser = self.XMLParser(target=Target())
3815
3816 parser.feed("<TAG/>")
3817 done = parser.close()
3818
3819 self.assertEqual("DONE", done)
3820 self.assertEqual(["start", "end"], events)
3821
3823 assertEqual = self.assertEqual
3824
3825 events = []
3826 class Target(object):
3827 def start(self, tag, attrib):
3828 events.append("start")
3829 assertEqual("TAG", tag)
3830 raise ValueError("TEST")
3831 def end(self, tag):
3832 events.append("end")
3833 assertEqual("TAG", tag)
3834 def close(self):
3835 return "DONE"
3836
3837 parser = self.XMLParser(target=Target())
3838
3839 try:
3840 parser.feed("<TAG/>")
3841 except ValueError:
3842 self.assertTrue('TEST' in str(sys.exc_info()[1]))
3843 else:
3844 self.assertTrue(False)
3845 if 'lxml' in self.etree.__name__:
3846 self.assertEqual(["start"], events)
3847 else:
3848 # cElementTree calls end() as well
3849 self.assertTrue("start" in events)
3850
3852 assertEqual = self.assertEqual
3853
3854 events = []
3855 class Target(object):
3856 def start(self, tag, attrib):
3857 events.append("start")
3858 assertEqual("TAG", tag)
3859 def end(self, tag):
3860 events.append("end")
3861 assertEqual("TAG", tag)
3862 raise ValueError("TEST")
3863 def close(self):
3864 return "DONE"
3865
3866 parser = self.XMLParser(target=Target())
3867
3868 try:
3869 parser.feed("<TAG/>")
3870 except ValueError:
3871 self.assertTrue('TEST' in str(sys.exc_info()[1]))
3872 else:
3873 self.assertTrue(False)
3874 self.assertEqual(["start", "end"], events)
3875
3877 assertEqual = self.assertEqual
3878
3879 events = []
3880 class Target(object):
3881 def start(self, tag, attrib):
3882 events.append("start")
3883 assertEqual("TAG", tag)
3884 def end(self, tag):
3885 events.append("end")
3886 assertEqual("TAG", tag)
3887 def close(self):
3888 raise ValueError("TEST")
3889
3890 parser = self.XMLParser(target=Target())
3891
3892 try:
3893 parser.feed("<TAG/>")
3894 parser.close()
3895 except ValueError:
3896 self.assertTrue('TEST' in str(sys.exc_info()[1]))
3897 else:
3898 self.assertTrue(False)
3899 self.assertEqual(["start", "end"], events)
3900
3902 assertEqual = self.assertEqual
3903
3904 events = []
3905 class Target(object):
3906 def start(self, tag, attrib):
3907 events.append("start")
3908 assertEqual("TAG", tag)
3909 raise IndexError("TEST-IE")
3910 def end(self, tag):
3911 events.append("end")
3912 assertEqual("TAG", tag)
3913 def close(self):
3914 raise ValueError("TEST-VE")
3915
3916 parser = self.XMLParser(target=Target())
3917
3918 try:
3919 parser.feed("<TAG/>")
3920 parser.close()
3921 except IndexError:
3922 if 'lxml' in self.etree.__name__:
3923 # we try not to swallow the initial exception in Py2
3924 self.assertTrue(sys.version_info[0] < 3)
3925 self.assertTrue('TEST-IE' in str(sys.exc_info()[1]))
3926 except ValueError:
3927 if 'lxml' in self.etree.__name__:
3928 self.assertTrue(sys.version_info[0] >= 3)
3929 self.assertTrue('TEST-VE' in str(sys.exc_info()[1]))
3930 else:
3931 self.assertTrue(False)
3932
3933 if 'lxml' in self.etree.__name__:
3934 self.assertEqual(["start"], events)
3935 else:
3936 # cElementTree calls end() as well
3937 self.assertTrue("start" in events)
3938
3940 assertEqual = self.assertEqual
3941 assertFalse = self.assertFalse
3942 Element = self.etree.Element
3943
3944 events = []
3945 class Target(object):
3946 def start(self, tag, attrib):
3947 events.append("start")
3948 assertFalse(attrib)
3949 assertEqual("TAG", tag)
3950 def end(self, tag):
3951 events.append("end")
3952 assertEqual("TAG", tag)
3953 def close(self):
3954 return Element("DONE")
3955
3956 parser = self.XMLParser(target=Target())
3957 tree = self.etree.ElementTree()
3958 tree.parse(BytesIO("<TAG/>"), parser=parser)
3959
3960 self.assertEqual("DONE", tree.getroot().tag)
3961 self.assertEqual(["start", "end"], events)
3962
3964 assertEqual = self.assertEqual
3965
3966 events = []
3967 class Target(object):
3968 def start(self, tag, attrib):
3969 events.append("start-" + tag)
3970 for name, value in attrib.items():
3971 assertEqual(tag + name, value)
3972 def end(self, tag):
3973 events.append("end-" + tag)
3974 def close(self):
3975 return "DONE"
3976
3977 parser = self.XMLParser(target=Target())
3978
3979 parser.feed('<root a="roota" b="rootb"><sub c="subc"/></root>')
3980 done = parser.close()
3981
3982 self.assertEqual("DONE", done)
3983 self.assertEqual(["start-root", "start-sub", "end-sub", "end-root"],
3984 events)
3985
3987 events = []
3988 class Target(object):
3989 def start(self, tag, attrib):
3990 events.append("start-" + tag)
3991 def end(self, tag):
3992 events.append("end-" + tag)
3993 def data(self, data):
3994 events.append("data-" + data)
3995 def close(self):
3996 return "DONE"
3997
3998 parser = self.XMLParser(target=Target())
3999
4000 parser.feed('<root>A<sub/>B</root>')
4001 done = parser.close()
4002
4003 self.assertEqual("DONE", done)
4004 self.assertEqual(["start-root", "data-A", "start-sub",
4005 "end-sub", "data-B", "end-root"],
4006 events)
4007
4013 def _flush_data(self):
4014 if self._data:
4015 events.append("data-" + ''.join(self._data))
4016 del self._data[:]
4017 def start(self, tag, attrib):
4018 self._flush_data()
4019 events.append("start-" + tag)
4020 def end(self, tag):
4021 self._flush_data()
4022 events.append("end-" + tag)
4023 def data(self, data):
4024 self._data.append(data)
4025 def close(self):
4026 self._flush_data()
4027 return "DONE"
4028
4029 parser = self.XMLParser(target=Target())
4030
4031 dtd = '''
4032 <!DOCTYPE root [
4033 <!ELEMENT root (sub*)>
4034 <!ELEMENT sub (#PCDATA)>
4035 <!ENTITY ent "an entity">
4036 ]>
4037 '''
4038 parser.feed(dtd+'<root><sub/><sub>this is &ent;</sub><sub/></root>')
4039 done = parser.close()
4040
4041 self.assertEqual("DONE", done)
4042 self.assertEqual(["start-root", "start-sub", "end-sub", "start-sub",
4043 "data-this is an entity",
4044 "end-sub", "start-sub", "end-sub", "end-root"],
4045 events)
4046
4047 required_versions_ET['test_parser_target_entity_unknown'] = (1,3)
4053 def _flush_data(self):
4054 if self._data:
4055 events.append("data-" + ''.join(self._data))
4056 del self._data[:]
4057 def start(self, tag, attrib):
4058 self._flush_data()
4059 events.append("start-" + tag)
4060 def end(self, tag):
4061 self._flush_data()
4062 events.append("end-" + tag)
4063 def data(self, data):
4064 self._data.append(data)
4065 def close(self):
4066 self._flush_data()
4067 return "DONE"
4068
4069 parser = self.XMLParser(target=Target())
4070
4071 def feed():
4072 parser.feed('<root><sub/><sub>some &ent;</sub><sub/></root>')
4073 parser.close()
4074
4075 self.assertRaises(self.etree.ParseError, feed)
4076
4077 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4082 def end(self, tag):
4083 self.append(("end", tag))
4084 def data(self, text):
4085 pass
4086 def pi(self, target, data):
4087 self.append(("pi", target, data))
4088 def comment(self, data):
4089 self.append(("comment", data))
4090 def start_ns(self, prefix, uri):
4091 self.append(("start-ns", prefix, uri))
4092 def end_ns(self, prefix):
4093 self.append(("end-ns", prefix))
4094
4095 builder = Builder()
4096 parser = self.etree.XMLParser(target=builder)
4097 parser.feed(textwrap.dedent("""\
4098 <?pi data?>
4099 <!-- comment -->
4100 <root xmlns='namespace'>
4101 <element key='value'>text</element>
4102 <element>text</element>tail
4103 <empty-element/>
4104 </root>
4105 """))
4106 self.assertEqual(builder, [
4107 ('pi', 'pi', 'data'),
4108 ('comment', ' comment '),
4109 ('start-ns', '', 'namespace'),
4110 ('start', '{namespace}root'),
4111 ('start', '{namespace}element'),
4112 ('end', '{namespace}element'),
4113 ('start', '{namespace}element'),
4114 ('end', '{namespace}element'),
4115 ('start', '{namespace}empty-element'),
4116 ('end', '{namespace}empty-element'),
4117 ('end', '{namespace}root'),
4118 ('end-ns', ''),
4119 ])
4120
4121 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4126
4127 builder = Builder()
4128 parser = self.etree.XMLParser(target=builder)
4129 parser.feed(textwrap.dedent("""\
4130 <?pi data?>
4131 <!-- comment -->
4132 <root xmlns='namespace' xmlns:p='pns'>
4133 <element key='value'>text</element>
4134 <p:element>text</p:element>tail
4135 <empty-element/>
4136 </root>
4137 """))
4138 self.assertEqual(builder, [
4139 ('end-ns', 'p'),
4140 ('end-ns', ''),
4141 ])
4142
4144 builder = self.etree.TreeBuilder()
4145 el = builder.start("root", {'a':'A', 'b':'B'})
4146 self.assertEqual("root", el.tag)
4147 self.assertEqual({'a':'A', 'b':'B'}, el.attrib)
4148 builder.data("ROOTTEXT")
4149 el = builder.start("child", {'x':'X', 'y':'Y'})
4150 self.assertEqual("child", el.tag)
4151 self.assertEqual({'x':'X', 'y':'Y'}, el.attrib)
4152 builder.data("CHILDTEXT")
4153 el = builder.end("child")
4154 self.assertEqual("child", el.tag)
4155 self.assertEqual({'x':'X', 'y':'Y'}, el.attrib)
4156 self.assertEqual("CHILDTEXT", el.text)
4157 self.assertEqual(None, el.tail)
4158 builder.data("CHILDTAIL")
4159 root = builder.end("root")
4160
4161 self.assertEqual("root", root.tag)
4162 self.assertEqual("ROOTTEXT", root.text)
4163 self.assertEqual("CHILDTEXT", root[0].text)
4164 self.assertEqual("CHILDTAIL", root[0].tail)
4165
4167 parser = self.XMLParser(target=self.etree.TreeBuilder())
4168 parser.feed('<root>ROOTTEXT<child>CHILDTEXT</child>CHILDTAIL</root>')
4169 root = parser.close()
4170
4171 self.assertEqual("root", root.tag)
4172 self.assertEqual("ROOTTEXT", root.text)
4173 self.assertEqual("CHILDTEXT", root[0].text)
4174 self.assertEqual("CHILDTAIL", root[0].tail)
4175
4176 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4178 ET = self.etree
4179 b = ET.TreeBuilder()
4180 self.assertEqual(b.comment('ctext').tag, ET.Comment)
4181 self.assertEqual(b.comment('ctext').text, 'ctext')
4182
4183 b = ET.TreeBuilder(comment_factory=ET.Comment)
4184 self.assertEqual(b.comment('ctext').tag, ET.Comment)
4185 self.assertEqual(b.comment('ctext').text, 'ctext')
4186
4187 #b = ET.TreeBuilder(comment_factory=len)
4188 #self.assertEqual(b.comment('ctext'), len('ctext'))
4189
4190 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4192 ET = self.etree
4193 is_lxml = ET.__name__ == 'lxml.etree'
4194
4195 b = ET.TreeBuilder()
4196 self.assertEqual(b.pi('target', None).tag, ET.PI)
4197 if is_lxml:
4198 self.assertEqual(b.pi('target', None).target, 'target')
4199 else:
4200 self.assertEqual(b.pi('target', None).text, 'target')
4201
4202 b = ET.TreeBuilder(pi_factory=ET.PI)
4203 self.assertEqual(b.pi('target').tag, ET.PI)
4204 if is_lxml:
4205 self.assertEqual(b.pi('target').target, "target")
4206 else:
4207 self.assertEqual(b.pi('target').text, "target")
4208 self.assertEqual(b.pi('pitarget', ' text ').tag, ET.PI)
4209 if is_lxml:
4210 self.assertEqual(b.pi('pitarget', ' text ').target, "pitarget")
4211 self.assertEqual(b.pi('pitarget', ' text ').text, " text ")
4212 else:
4213 self.assertEqual(b.pi('pitarget', ' text ').text, "pitarget text ")
4214
4215 #b = ET.TreeBuilder(pi_factory=lambda target, text: (len(target), text))
4216 #self.assertEqual(b.pi('target'), (len('target'), None))
4217 #self.assertEqual(b.pi('pitarget', ' text '), (len('pitarget'), ' text '))
4218
4220 # Issue #37399: The tail of an ignored comment could overwrite the text before it.
4221 ET = self.etree
4222 class TreeBuilderSubclass(ET.TreeBuilder):
4223 pass
4224
4225 if ET.__name__ == 'lxml.etree':
4226 def assert_content(a):
4227 self.assertEqual(a.text, "text")
4228 self.assertEqual(a[0].tail, "tail")
4229 else:
4230 def assert_content(a):
4231 self.assertEqual(a.text, "texttail")
4232
4233 xml = "<a>text<!-- comment -->tail</a>"
4234 a = ET.fromstring(xml)
4235 assert_content(a)
4236
4237 parser = ET.XMLParser(target=TreeBuilderSubclass())
4238 parser.feed(xml)
4239 a = parser.close()
4240 assert_content(a)
4241
4242 xml = "<a>text<?pi data?>tail</a>"
4243 a = ET.fromstring(xml)
4244 assert_content(a)
4245
4246 xml = "<a>text<?pi data?>tail</a>"
4247 parser = ET.XMLParser(target=TreeBuilderSubclass())
4248 parser.feed(xml)
4249 a = parser.close()
4250 assert_content(a)
4251
4252 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4254 # Issue #37399: The tail of an ignored comment could overwrite the text before it.
4255 # Test appending tails to comments/pis.
4256 ET = self.etree
4257 class TreeBuilderSubclass(ET.TreeBuilder):
4258 pass
4259
4260 xml = "<a>text<?pi1?> <!-- comment -->\n<?pi2?>tail</a>"
4261 parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True, insert_pis=False))
4262 parser.feed(xml)
4263 a = parser.close()
4264 self.assertEqual(a[0].text, ' comment ')
4265 self.assertEqual(a[0].tail, '\ntail')
4266 self.assertEqual(a.text, "text ")
4267
4268 parser = ET.XMLParser(target=TreeBuilderSubclass(insert_comments=True, insert_pis=False))
4269 parser.feed(xml)
4270 a = parser.close()
4271 self.assertEqual(a[0].text, ' comment ')
4272 self.assertEqual(a[0].tail, '\ntail')
4273 self.assertEqual(a.text, "text ")
4274
4275 xml = "<a>text<!-- comment -->\n<?pi data?>tail</a>"
4276 parser = ET.XMLParser(target=ET.TreeBuilder(insert_pis=True, insert_comments=False))
4277 parser.feed(xml)
4278 a = parser.close()
4279 self.assertEqual(a[0].text[-4:], 'data')
4280 self.assertEqual(a[0].tail, 'tail')
4281 self.assertEqual(a.text, "text\n")
4282
4283 parser = ET.XMLParser(target=TreeBuilderSubclass(insert_pis=True, insert_comments=False))
4284 parser.feed(xml)
4285 a = parser.close()
4286 self.assertEqual(a[0].text[-4:], 'data')
4287 self.assertEqual(a[0].tail, 'tail')
4288 self.assertEqual(a.text, "text\n")
4289
4290 # helper methods
4291
4293 """Write out element for comparison.
4294 """
4295 data = self.etree.tostring(element, encoding=encoding)
4296 return canonicalize(data)
4297
4299 """Write out element for comparison, using real file.
4300 """
4301 ElementTree = self.etree.ElementTree
4302 with tmpfile() as filename:
4303 with open(filename, 'wb') as f:
4304 tree = ElementTree(element=element)
4305 tree.write(f, encoding=encoding)
4306 with open(filename, 'rb') as f:
4307 data = f.read()
4308 return canonicalize(data)
4309
4311 """Writes element out and checks whether it is expected.
4312
4313 Does this two ways; once using BytesIO, once using a real file.
4314 """
4315 if isinstance(expected, unicode):
4316 expected = expected.encode(encoding)
4317 self.assertEqual(expected, self._writeElement(element, encoding))
4318 self.assertEqual(expected, self._writeElementFile(element, encoding))
4319
4321 "Checks if the result XML byte string specifies the encoding."
4322 enc_re = r"<\?xml[^>]+ encoding=[\"']([^\"']+)[\"']"
4323 if isinstance(result, str):
4324 has_encoding = re.compile(enc_re).match
4325 else:
4326 has_encoding = re.compile(_bytes(enc_re)).match
4327 self.assertTrue(has_encoding(result))
4328 result_encoding = has_encoding(result).group(1)
4329 self.assertEqual(result_encoding.upper(), encoding.upper())
4330
4332 return self.etree.tostring(tree.getroot()).replace(
4333 _bytes(' '), _bytes('')).replace(_bytes('\n'), _bytes(''))
4334
4337
4339 self.assertTrue(hasattr(element, 'tag'))
4340 self.assertTrue(hasattr(element, 'attrib'))
4341 self.assertTrue(hasattr(element, 'text'))
4342 self.assertTrue(hasattr(element, 'tail'))
4343 self._check_string(element.tag)
4344 self._check_mapping(element.attrib)
4345 if element.text is not None:
4346 self._check_string(element.text)
4347 if element.tail is not None:
4348 self._check_string(element.tail)
4349
4351 len(string)
4352 for char in string:
4353 self.assertEqual(1, len(char))
4354 new_string = string + ""
4355 new_string = string + " "
4356 string[:0]
4357
4359 len(mapping)
4360 keys = mapping.keys()
4361 values = mapping.values()
4362 items = mapping.items()
4363 for key in keys:
4364 item = mapping[key]
4365 mapping["key"] = "value"
4366 self.assertEqual("value", mapping["key"])
4367
4370 etree = None
4371
4374
4377
4379 """Create an Element with a tag 'a', with the given amount of children
4380 named 'a0', 'a1' ... and so on.
4381
4382 """
4383 e = self.etree.Element('a')
4384 for i in range(numchildren):
4385 self.etree.SubElement(e, 'a%s' % i)
4386 return e
4387
4389 e = self._make_elem_with_children(10)
4390
4391 self.assertEqual(e[1].tag, 'a1')
4392 self.assertEqual(e[-2].tag, 'a8')
4393
4394 self.assertRaises(IndexError, lambda: e[12])
4395 self.assertRaises(IndexError, lambda: e[-12])
4396
4398 e = self._make_elem_with_children(6)
4399
4400 self.assertEqual(self._elem_tags(e[3:]), ['a3', 'a4', 'a5'])
4401 self.assertEqual(self._elem_tags(e[3:6]), ['a3', 'a4', 'a5'])
4402 self.assertEqual(self._elem_tags(e[3:16]), ['a3', 'a4', 'a5'])
4403 self.assertEqual(self._elem_tags(e[3:5]), ['a3', 'a4'])
4404 self.assertEqual(self._elem_tags(e[3:-1]), ['a3', 'a4'])
4405 self.assertEqual(self._elem_tags(e[:2]), ['a0', 'a1'])
4406
4408 e = self._make_elem_with_children(10)
4409
4410 self.assertEqual(self._elem_tags(e[8:10:1]), ['a8', 'a9'])
4411 self.assertEqual(self._elem_tags(e[::3]), ['a0', 'a3', 'a6', 'a9'])
4412 self.assertEqual(self._elem_tags(e[::8]), ['a0', 'a8'])
4413 self.assertEqual(self._elem_tags(e[1::8]), ['a1', 'a9'])
4414 self.assertEqual(self._elem_tags(e[3::sys.maxsize]), ['a3'])
4415 self.assertEqual(self._elem_tags(e[3::sys.maxsize<<64]), ['a3'])
4416
4418 e = self._make_elem_with_children(4)
4419
4420 self.assertEqual(self._elem_tags(e[::-1]), ['a3', 'a2', 'a1', 'a0'])
4421 self.assertEqual(self._elem_tags(e[::-2]), ['a3', 'a1'])
4422 self.assertEqual(self._elem_tags(e[3::-sys.maxsize]), ['a3'])
4423 self.assertEqual(self._elem_tags(e[3::-sys.maxsize-1]), ['a3'])
4424 self.assertEqual(self._elem_tags(e[3::-sys.maxsize<<64]), ['a3'])
4425
4427 e = self._make_elem_with_children(4)
4428 del e[0:2]
4429 self.assertEqual(self._subelem_tags(e), ['a2', 'a3'])
4430
4431 e = self._make_elem_with_children(4)
4432 del e[0:]
4433 self.assertEqual(self._subelem_tags(e), [])
4434
4435 e = self._make_elem_with_children(4)
4436 del e[::-1]
4437 self.assertEqual(self._subelem_tags(e), [])
4438
4439 e = self._make_elem_with_children(4)
4440 del e[::-2]
4441 self.assertEqual(self._subelem_tags(e), ['a0', 'a2'])
4442
4443 e = self._make_elem_with_children(4)
4444 del e[1::2]
4445 self.assertEqual(self._subelem_tags(e), ['a0', 'a2'])
4446
4447 e = self._make_elem_with_children(2)
4448 del e[::2]
4449 self.assertEqual(self._subelem_tags(e), ['a1'])
4450
4452 e = self._make_elem_with_children(4)
4453 e[1] = self.etree.Element('b')
4454 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3'])
4455
4456 e[-2] = self.etree.Element('c')
4457 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3'])
4458
4459 with self.assertRaises(IndexError):
4460 e[5] = self.etree.Element('d')
4461 with self.assertRaises(IndexError):
4462 e[-5] = self.etree.Element('d')
4463 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3'])
4464
4466 e = self._make_elem_with_children(4)
4467 e[1:3] = [self.etree.Element('b%s' % i) for i in range(2)]
4468 self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'a3'])
4469
4470 e = self._make_elem_with_children(4)
4471 e[1:3] = [self.etree.Element('b')]
4472 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a3'])
4473
4474 e = self._make_elem_with_children(4)
4475 e[1:3] = [self.etree.Element('b%s' % i) for i in range(3)]
4476 self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'b2', 'a3'])
4477
4479 e = self._make_elem_with_children(6)
4480 e[1:5:2] = [self.etree.Element('b%s' % i) for i in range(2)]
4481 self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'a2', 'b1', 'a4', 'a5'])
4482
4483 e = self._make_elem_with_children(6)
4484 with self.assertRaises(ValueError):
4485 e[1:5:2] = [self.etree.Element('b')]
4486 with self.assertRaises(ValueError):
4487 e[1:5:2] = [self.etree.Element('b%s' % i) for i in range(3)]
4488 with self.assertRaises(ValueError):
4489 e[1:5:2] = []
4490 self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3', 'a4', 'a5'])
4491
4492 e = self._make_elem_with_children(4)
4493 e[1::sys.maxsize] = [self.etree.Element('b')]
4494 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3'])
4495 e[1::sys.maxsize<<64] = [self.etree.Element('c')]
4496 self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3'])
4497
4499 e = self._make_elem_with_children(4)
4500 e[2:0:-1] = [self.etree.Element('b%s' % i) for i in range(2)]
4501 self.assertEqual(self._subelem_tags(e), ['a0', 'b1', 'b0', 'a3'])
4502
4503 e = self._make_elem_with_children(4)
4504 with self.assertRaises(ValueError):
4505 e[2:0:-1] = [self.etree.Element('b')]
4506 with self.assertRaises(ValueError):
4507 e[2:0:-1] = [self.etree.Element('b%s' % i) for i in range(3)]
4508 with self.assertRaises(ValueError):
4509 e[2:0:-1] = []
4510 self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3'])
4511
4512 e = self._make_elem_with_children(4)
4513 e[1::-sys.maxsize] = [self.etree.Element('b')]
4514 self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3'])
4515 e[1::-sys.maxsize-1] = [self.etree.Element('c')]
4516 self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3'])
4517 e[1::-sys.maxsize<<64] = [self.etree.Element('d')]
4518 self.assertEqual(self._subelem_tags(e), ['a0', 'd', 'a2', 'a3'])
4519
4522 etree = None
4523
4525 if 'ElementTree' in self.etree.__name__:
4526 # ElementTree's API is a bit unwieldy in Py3.4
4527 root = parser._close_and_return_root()
4528 else:
4529 root = parser.close()
4530 return root
4531
4533 if chunk_size is None:
4534 parser.feed(data)
4535 else:
4536 for i in range(0, len(data), chunk_size):
4537 parser.feed(data[i:i+chunk_size])
4538
4540 self.assertEqual(
4541 [(event, (elem.tag, elem.text))
4542 for event, elem in islice(parser.read_events(), max_events)],
4543 expected)
4544
4549
4554
4556 for chunk_size in (None, 1, 5):
4557 #with self.subTest(chunk_size=chunk_size):
4558 parser = self.etree.XMLPullParser()
4559 self.assert_event_tags(parser, [])
4560 self._feed(parser, "<!-- comment -->\n", chunk_size)
4561 self.assert_event_tags(parser, [])
4562 self._feed(parser,
4563 "<root>\n <element key='value'>text</element",
4564 chunk_size)
4565 self.assert_event_tags(parser, [])
4566 self._feed(parser, ">\n", chunk_size)
4567 self.assert_event_tags(parser, [('end', 'element')])
4568 self._feed(parser, "<element>text</element>tail\n", chunk_size)
4569 self._feed(parser, "<empty-element/>\n", chunk_size)
4570 self.assert_event_tags(parser, [
4571 ('end', 'element'),
4572 ('end', 'empty-element'),
4573 ])
4574 self._feed(parser, "</root>\n", chunk_size)
4575 self.assert_event_tags(parser, [('end', 'root')])
4576 root = self._close_and_return_root(parser)
4577 self.assertEqual(root.tag, 'root')
4578
4580 parser = self.etree.XMLPullParser()
4581 it = parser.read_events()
4582 self._feed(parser, "<root>\n <element key='value'>text</element>\n")
4583 action, elem = next(it)
4584 self.assertEqual((action, elem.tag), ('end', 'element'))
4585 self._feed(parser, "</root>\n")
4586 action, elem = next(it)
4587 self.assertEqual((action, elem.tag), ('end', 'root'))
4588 with self.assertRaises(StopIteration):
4589 next(it)
4590
4592 parser = self.etree.XMLPullParser()
4593 self.assert_event_tags(parser, [])
4594 self._feed(parser, "<!-- comment -->\n")
4595 self.assert_event_tags(parser, [])
4596 self._feed(parser, "<root xmlns='namespace'>\n")
4597 self.assert_event_tags(parser, [])
4598 self._feed(parser, "<element key='value'>text</element")
4599 self.assert_event_tags(parser, [])
4600 self._feed(parser, ">\n")
4601 self.assert_event_tags(parser, [('end', '{namespace}element')])
4602 self._feed(parser, "<element>text</element>tail\n")
4603 self._feed(parser, "<empty-element/>\n")
4604 self.assert_event_tags(parser, [
4605 ('end', '{namespace}element'),
4606 ('end', '{namespace}empty-element'),
4607 ])
4608 self._feed(parser, "</root>\n")
4609 self.assert_event_tags(parser, [('end', '{namespace}root')])
4610 root = self._close_and_return_root(parser)
4611 self.assertEqual(root.tag, '{namespace}root')
4612
4614 parser = self.etree.XMLPullParser(events=('start-ns', 'end-ns'))
4615 self._feed(parser, "<!-- comment -->\n")
4616 self._feed(parser, "<root xmlns='namespace'>\n")
4617 self.assertEqual(
4618 list(parser.read_events()),
4619 [('start-ns', ('', 'namespace'))])
4620 self._feed(parser, "<element key='value'>text</element")
4621 self._feed(parser, ">\n")
4622 self._feed(parser, "<element>text</element>tail\n")
4623 self._feed(parser, "<empty-element/>\n")
4624 self._feed(parser, "</root>\n")
4625 self.assertEqual(list(parser.read_events()), [('end-ns', None)])
4626 parser.close()
4627
4629 parser = self.etree.XMLPullParser(events=['end-ns'])
4630 self._feed(parser, "<!-- comment -->\n")
4631 self._feed(parser, "<root xmlns='namespace' xmlns:a='abc' xmlns:b='xyz'>\n")
4632 self.assertEqual(list(parser.read_events()), [])
4633 self._feed(parser, "<a:element key='value'>text</a:element")
4634 self._feed(parser, ">\n")
4635 self._feed(parser, "<b:element>text</b:element>tail\n")
4636 self._feed(parser, "<empty-element/>\n")
4637 self.assertEqual(list(parser.read_events()), [])
4638 self._feed(parser, "</root>\n")
4639 self.assertEqual(list(parser.read_events()), [
4640 ('end-ns', None),
4641 ('end-ns', None),
4642 ('end-ns', None),
4643 ])
4644 parser.close()
4645
4646 @et_needs_pyversion(3,8)
4648 parser = self.etree.XMLPullParser(events=('start-ns', 'start', 'end'))
4649 self._feed(parser, "<tag xmlns='abc' xmlns:p='xyz'>\n")
4650 self.assert_event_tuples(parser, [
4651 ('start-ns', ('', 'abc')),
4652 ('start-ns', ('p', 'xyz')),
4653 ], max_events=2)
4654 self.assert_event_tags(parser, [
4655 ('start', '{abc}tag'),
4656 ], max_events=1)
4657
4658 self._feed(parser, "<child />\n")
4659 self.assert_event_tags(parser, [
4660 ('start', '{abc}child'),
4661 ('end', '{abc}child'),
4662 ])
4663
4664 self._feed(parser, "</tag>\n")
4665 parser.close()
4666 self.assert_event_tags(parser, [
4667 ('end', '{abc}tag'),
4668 ])
4669
4670 @et_needs_pyversion(3,8)
4672 parser = self.etree.XMLPullParser(events=('start-ns', 'start', 'end', 'end-ns'))
4673 self._feed(parser, "<tag xmlns='abc' xmlns:p='xyz'>\n")
4674 self.assert_event_tuples(parser, [
4675 ('start-ns', ('', 'abc')),
4676 ('start-ns', ('p', 'xyz')),
4677 ], max_events=2)
4678 self.assert_event_tags(parser, [
4679 ('start', '{abc}tag'),
4680 ], max_events=1)
4681
4682 self._feed(parser, "<child />\n")
4683 self.assert_event_tags(parser, [
4684 ('start', '{abc}child'),
4685 ('end', '{abc}child'),
4686 ])
4687
4688 self._feed(parser, "</tag>\n")
4689 parser.close()
4690 self.assert_event_tags(parser, [
4691 ('end', '{abc}tag'),
4692 ], max_events=1)
4693 self.assert_event_tuples(parser, [
4694 ('end-ns', None),
4695 ('end-ns', None),
4696 ])
4697
4699 parser = self.etree.XMLPullParser(events=())
4700 self._feed(parser, "<root/>\n")
4701 self.assert_event_tags(parser, [])
4702
4703 parser = self.etree.XMLPullParser(events=('start', 'end'))
4704 self._feed(parser, "<!-- text here -->\n")
4705 self.assert_events(parser, [])
4706
4707 parser = self.etree.XMLPullParser(events=('start', 'end'))
4708 self._feed(parser, "<root>\n")
4709 self.assert_event_tags(parser, [('start', 'root')])
4710 self._feed(parser, "<element key='value'>text</element")
4711 self.assert_event_tags(parser, [('start', 'element')])
4712 self._feed(parser, ">\n")
4713 self.assert_event_tags(parser, [('end', 'element')])
4714 self._feed(parser,
4715 "<element xmlns='foo'>text<empty-element/></element>tail\n")
4716 self.assert_event_tags(parser, [
4717 ('start', '{foo}element'),
4718 ('start', '{foo}empty-element'),
4719 ('end', '{foo}empty-element'),
4720 ('end', '{foo}element'),
4721 ])
4722 self._feed(parser, "</root>")
4723 root = self._close_and_return_root(parser)
4724 self.assert_event_tags(parser, [('end', 'root')])
4725 self.assertEqual(root.tag, 'root')
4726
4727 parser = self.etree.XMLPullParser(events=('start',))
4728 self._feed(parser, "<!-- comment -->\n")
4729 self.assert_event_tags(parser, [])
4730 self._feed(parser, "<root>\n")
4731 self.assert_event_tags(parser, [('start', 'root')])
4732 self._feed(parser, "<element key='value'>text</element")
4733 self.assert_event_tags(parser, [('start', 'element')])
4734 self._feed(parser, ">\n")
4735 self.assert_event_tags(parser, [])
4736 self._feed(parser,
4737 "<element xmlns='foo'>text<empty-element/></element>tail\n")
4738 self.assert_event_tags(parser, [
4739 ('start', '{foo}element'),
4740 ('start', '{foo}empty-element'),
4741 ])
4742 self._feed(parser, "</root>")
4743 root = self._close_and_return_root(parser)
4744 self.assertEqual(root.tag, 'root')
4745
4746 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4748 parser = self.etree.XMLPullParser(events=('start', 'comment', 'end'))
4749 self._feed(parser, "<!-- text here -->\n")
4750 self.assert_events(parser, [('comment', (self.etree.Comment, ' text here '))])
4751 self._feed(parser, "<!-- more text here -->\n")
4752 self.assert_events(parser, [('comment', (self.etree.Comment, ' more text here '))])
4753 self._feed(parser, "<root-tag>text")
4754 self.assert_event_tags(parser, [('start', 'root-tag')])
4755 self._feed(parser, "<!-- inner comment-->\n")
4756 self.assert_events(parser, [('comment', (self.etree.Comment, ' inner comment'))])
4757 self._feed(parser, "</root-tag>\n")
4758 self.assert_event_tags(parser, [('end', 'root-tag')])
4759 self._feed(parser, "<!-- outer comment -->\n")
4760 self.assert_events(parser, [('comment', (self.etree.Comment, ' outer comment '))])
4761
4762 parser = self.etree.XMLPullParser(events=('comment',))
4763 self._feed(parser, "<!-- text here -->\n")
4764 self.assert_events(parser, [('comment', (self.etree.Comment, ' text here '))])
4765
4766 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4768 # Note: lxml's PIs have target+text, ET's PIs have both in "text"
4769 parser = self.etree.XMLPullParser(events=('start', 'pi', 'end'))
4770 self._feed(parser, "<?pitarget?>\n")
4771 self.assert_event_tags(parser, [('pi', self.etree.PI)])
4772 parser = self.etree.XMLPullParser(events=('pi',))
4773 self._feed(parser, "<?pitarget some text ?>\n")
4774 self.assert_event_tags(parser, [('pi', self.etree.PI)])
4775
4777 # Test that events can be some sequence that's not just a tuple or list
4778 eventset = {'end', 'start'}
4779 parser = self.etree.XMLPullParser(events=eventset)
4780 self._feed(parser, "<foo>bar</foo>")
4781 self.assert_event_tags(parser, [('start', 'foo'), ('end', 'foo')])
4782
4783 class DummyIter(object):
4784 def __init__(self):
4785 self.events = iter(['start', 'end', 'start-ns'])
4786 def __iter__(self):
4787 return self
4788 def __next__(self):
4789 return next(self.events)
4790 def next(self):
4791 return next(self.events)
4792
4793 parser = self.etree.XMLPullParser(events=DummyIter())
4794 self._feed(parser, "<foo>bar</foo>")
4795 self.assert_event_tags(parser, [('start', 'foo'), ('end', 'foo')])
4796
4798 with self.assertRaises(ValueError):
4799 self.etree.XMLPullParser(events=('start', 'end', 'bogus'))
4800
4803 etree = None
4804 maxDiff = None
4805
4806 if not hasattr(unittest.TestCase, 'subTest'):
4807 @contextmanager
4809 try:
4810 yield
4811 except unittest.SkipTest:
4812 raise
4813 except Exception as e:
4814 print("Subtest {} failed: {}".format(name, e))
4815 raise
4816
4819
4820 #
4821 # simple roundtrip tests (from c14n.py)
4822
4825
4827 c14n_roundtrip = self.c14n_roundtrip
4828 # Basics
4829 self.assertEqual(c14n_roundtrip("<doc/>"), '<doc></doc>')
4830 self.assertEqual(c14n_roundtrip("<doc xmlns='uri'/>"), # FIXME
4831 '<doc xmlns="uri"></doc>')
4832 self.assertEqual(c14n_roundtrip("<prefix:doc xmlns:prefix='uri'/>"),
4833 '<prefix:doc xmlns:prefix="uri"></prefix:doc>')
4834 self.assertEqual(c14n_roundtrip("<doc xmlns:prefix='uri'><prefix:bar/></doc>"),
4835 '<doc><prefix:bar xmlns:prefix="uri"></prefix:bar></doc>')
4836 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/' />"),
4837 '<elem></elem>')
4838
4839 # C14N spec
4840 self.assertEqual(c14n_roundtrip("<doc>Hello, world!<!-- Comment 1 --></doc>"),
4841 '<doc>Hello, world!</doc>')
4842 self.assertEqual(c14n_roundtrip("<value>2</value>"),
4843 '<value>2</value>')
4844 self.assertEqual(c14n_roundtrip('<compute><![CDATA[value>"0" && value<"10" ?"valid":"error"]]></compute>'),
4845 '<compute>value>"0" && value<"10" ?"valid":"error"</compute>')
4846 self.assertEqual(c14n_roundtrip('''<compute expr='value>"0" && value<"10" ?"valid":"error"'>valid</compute>'''),
4847 '<compute expr="value>"0" && value<"10" ?"valid":"error"">valid</compute>')
4848 self.assertEqual(c14n_roundtrip("<norm attr=' '   
	 ' '/>"),
4849 '<norm attr=" \' 
	 \' "></norm>')
4850 self.assertEqual(c14n_roundtrip("<normNames attr=' A   
	 B '/>"),
4851 '<normNames attr=" A 
	 B "></normNames>')
4852 self.assertEqual(c14n_roundtrip("<normId id=' '   
	 ' '/>"),
4853 '<normId id=" \' 
	 \' "></normId>')
4854
4855 # fragments from PJ's tests
4856 #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>"),
4857 #'<doc xmlns:x="http://example.com/x"><b xmlns:y="http://example.com/y" a3="3" y:a1="1" y:a2="2"></b></doc>')
4858
4860 c14n_roundtrip = self.c14n_roundtrip
4861 xml = textwrap.dedent("""\
4862 <root xmlns:x="http://example.com/x">
4863 <a x:attr="attrx">
4864 <b>abtext</b>
4865 </a>
4866 <b>btext</b>
4867 <c>
4868 <x:d>dtext</x:d>
4869 </c>
4870 </root>
4871 """)
4872 self.assertEqual(
4873 c14n_roundtrip(xml, strip_text=True),
4874 '<root>'
4875 '<a xmlns:x="http://example.com/x" x:attr="attrx"><b>abtext</b></a>'
4876 '<b>btext</b>'
4877 '<c><x:d xmlns:x="http://example.com/x">dtext</x:d></c>'
4878 '</root>')
4879 self.assertEqual(
4880 c14n_roundtrip(xml, strip_text=True, exclude_attrs=['{http://example.com/x}attr']),
4881 '<root>'
4882 '<a><b>abtext</b></a>'
4883 '<b>btext</b>'
4884 '<c><x:d xmlns:x="http://example.com/x">dtext</x:d></c>'
4885 '</root>')
4886 self.assertEqual(
4887 c14n_roundtrip(xml, strip_text=True, exclude_tags=['{http://example.com/x}d']),
4888 '<root>'
4889 '<a xmlns:x="http://example.com/x" x:attr="attrx"><b>abtext</b></a>'
4890 '<b>btext</b>'
4891 '<c></c>'
4892 '</root>')
4893 self.assertEqual(
4894 c14n_roundtrip(xml, strip_text=True, exclude_attrs=['{http://example.com/x}attr'],
4895 exclude_tags=['{http://example.com/x}d']),
4896 '<root>'
4897 '<a><b>abtext</b></a>'
4898 '<b>btext</b>'
4899 '<c></c>'
4900 '</root>')
4901 self.assertEqual(
4902 c14n_roundtrip(xml, strip_text=True, exclude_tags=['a', 'b']),
4903 '<root>'
4904 '<c><x:d xmlns:x="http://example.com/x">dtext</x:d></c>'
4905 '</root>')
4906 self.assertEqual(
4907 c14n_roundtrip(xml, exclude_tags=['a', 'b']),
4908 '<root>\n'
4909 ' \n'
4910 ' \n'
4911 ' <c>\n'
4912 ' <x:d xmlns:x="http://example.com/x">dtext</x:d>\n'
4913 ' </c>\n'
4914 '</root>')
4915 self.assertEqual(
4916 c14n_roundtrip(xml, strip_text=True, exclude_tags=['{http://example.com/x}d', 'b']),
4917 '<root>'
4918 '<a xmlns:x="http://example.com/x" x:attr="attrx"></a>'
4919 '<c></c>'
4920 '</root>')
4921 self.assertEqual(
4922 c14n_roundtrip(xml, exclude_tags=['{http://example.com/x}d', 'b']),
4923 '<root>\n'
4924 ' <a xmlns:x="http://example.com/x" x:attr="attrx">\n'
4925 ' \n'
4926 ' </a>\n'
4927 ' \n'
4928 ' <c>\n'
4929 ' \n'
4930 ' </c>\n'
4931 '</root>')
4932
4933 #
4934 # basic method=c14n tests from the c14n 2.0 specification. uses
4935 # test files under xmltestdata/c14n-20.
4936
4937 # note that this uses generated C14N versions of the standard ET.write
4938 # output, not roundtripped C14N (see above).
4939
4941 datadir = os.path.join(os.path.dirname(__file__), "c14n-20")
4942 full_path = partial(os.path.join, datadir)
4943
4944 files = [filename[:-4] for filename in sorted(os.listdir(datadir))
4945 if filename.endswith('.xml')]
4946 input_files = [
4947 filename for filename in files
4948 if filename.startswith('in')
4949 ]
4950 configs = {
4951 filename: {
4952 # <c14n2:PrefixRewrite>sequential</c14n2:PrefixRewrite>
4953 option.tag.split('}')[-1]: ((option.text or '').strip(), option)
4954 for option in self.etree.parse(full_path(filename) + ".xml").getroot()
4955 }
4956 for filename in files
4957 if filename.startswith('c14n')
4958 }
4959
4960 tests = {
4961 input_file: [
4962 (filename, configs[filename.rsplit('_', 1)[-1]])
4963 for filename in files
4964 if filename.startswith('out_%s_' % input_file)
4965 and filename.rsplit('_', 1)[-1] in configs
4966 ]
4967 for input_file in input_files
4968 }
4969
4970 # Make sure we found all test cases.
4971 self.assertEqual(30, len([
4972 output_file for output_files in tests.values()
4973 for output_file in output_files]))
4974
4975 def get_option(config, option_name, default=None):
4976 return config.get(option_name, (default, ()))[0]
4977
4978 for input_file, output_files in tests.items():
4979 for output_file, config in output_files:
4980 keep_comments = get_option(
4981 config, 'IgnoreComments') == 'true' # no, it's right :)
4982 strip_text = get_option(
4983 config, 'TrimTextNodes') == 'true'
4984 rewrite_prefixes = get_option(
4985 config, 'PrefixRewrite') == 'sequential'
4986 if 'QNameAware' in config:
4987 qattrs = [
4988 "{%s}%s" % (el.get('NS'), el.get('Name'))
4989 for el in config['QNameAware'][1].findall(
4990 '{http://www.w3.org/2010/xml-c14n2}QualifiedAttr')
4991 ]
4992 qtags = [
4993 "{%s}%s" % (el.get('NS'), el.get('Name'))
4994 for el in config['QNameAware'][1].findall(
4995 '{http://www.w3.org/2010/xml-c14n2}Element')
4996 ]
4997 else:
4998 qtags = qattrs = None
4999
5000 # Build subtest description from config.
5001 config_descr = ','.join(
5002 "%s=%s" % (name, value or ','.join(c.tag.split('}')[-1] for c in children))
5003 for name, (value, children) in sorted(config.items())
5004 )
5005
5006 with self.subTest("{}({})".format(output_file, config_descr)):
5007 if input_file == 'inNsRedecl' and not rewrite_prefixes:
5008 self.skipTest(
5009 "Redeclared namespace handling is not supported in {}".format(
5010 output_file))
5011 if input_file == 'inNsSuperfluous' and not rewrite_prefixes:
5012 self.skipTest(
5013 "Redeclared namespace handling is not supported in {}".format(
5014 output_file))
5015 if 'QNameAware' in config and config['QNameAware'][1].find(
5016 '{http://www.w3.org/2010/xml-c14n2}XPathElement') is not None:
5017 self.skipTest(
5018 "QName rewriting in XPath text is not supported in {}".format(
5019 output_file))
5020
5021 f = full_path(input_file + ".xml")
5022 if input_file == 'inC14N5':
5023 # Hack: avoid setting up external entity resolution in the parser.
5024 with open(full_path('world.txt'), 'rb') as entity_file:
5025 with open(f, 'rb') as f:
5026 f = io.BytesIO(f.read().replace(b'&ent2;', entity_file.read().strip()))
5027
5028 text = self._canonicalize(
5029 f,
5030 with_comments=keep_comments,
5031 strip_text=strip_text,
5032 rewrite_prefixes=rewrite_prefixes,
5033 qname_aware_tags=qtags, qname_aware_attrs=qattrs)
5034
5035 with io.open(full_path(output_file + ".xml"), 'r', encoding='utf8') as f:
5036 expected = f.read()
5037 if input_file == 'inC14N3' and self.etree is not etree:
5038 # FIXME: cET resolves default attributes but ET does not!
5039 expected = expected.replace(' attr="default"', '')
5040 text = text.replace(' attr="default"', '')
5041 self.assertEqual(expected, text)
5042
5043
5044 if etree:
5047
5050
5053
5056
5058 - def _canonicalize(self, input_file, with_comments=True, strip_text=False,
5059 rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None,
5060 **options):
5061 if rewrite_prefixes or qname_aware_attrs or qname_aware_tags:
5062 self.skipTest("C14N 2.0 feature not supported with ElementTree.write()")
5063
5064 parser = self.etree.XMLParser(attribute_defaults=True, collect_ids=False)
5065 tree = self.etree.parse(input_file, parser)
5066 out = io.BytesIO()
5067 tree.write(
5068 out, method='c14n2',
5069 with_comments=with_comments, strip_text=strip_text,
5070 **options)
5071 return out.getvalue().decode('utf8')
5072
5074 - def _canonicalize(self, input_file, with_comments=True, strip_text=False,
5075 rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None,
5076 **options):
5077 if rewrite_prefixes or qname_aware_attrs or qname_aware_tags:
5078 self.skipTest("C14N 2.0 feature not supported with ElementTree.tostring()")
5079
5080 parser = self.etree.XMLParser(attribute_defaults=True, collect_ids=False)
5081 tree = self.etree.parse(input_file, parser)
5082 return self.etree.tostring(
5083 tree, method='c14n2',
5084 with_comments=with_comments, strip_text=strip_text,
5085 **options).decode('utf8')
5086
5087
5088 if ElementTree:
5100
5101 filter_by_version(
5102 ElementTreeTestCase,
5103 ElementTreeTestCase.required_versions_ET, ET_VERSION)
5104
5105 if hasattr(ElementTree, 'XMLPullParser'):
5108 else:
5109 ElementTreePullTestCase = None
5110
5111 if hasattr(ElementTree, 'canonicalize'):
5114 else:
5115 ElementTreeC14NTest = None
5119
5120
5121 if cElementTree:
5124
5125 filter_by_version(
5126 CElementTreeTestCase,
5127 CElementTreeTestCase.required_versions_cET, CET_VERSION)
5131
5134 suite = unittest.TestSuite()
5135 if etree:
5136 suite.addTests([unittest.makeSuite(ETreeTestCase)])
5137 suite.addTests([unittest.makeSuite(ETreePullTestCase)])
5138 suite.addTests([unittest.makeSuite(ETreeElementSlicingTest)])
5139 suite.addTests([unittest.makeSuite(ETreeC14NTest)])
5140 suite.addTests([unittest.makeSuite(ETreeC14N2WriteTest)])
5141 suite.addTests([unittest.makeSuite(ETreeC14N2TostringTest)])
5142 if ElementTree:
5143 suite.addTests([unittest.makeSuite(ElementTreeTestCase)])
5144 if ElementTreePullTestCase:
5145 suite.addTests([unittest.makeSuite(ElementTreePullTestCase)])
5146 if ElementTreeC14NTest:
5147 suite.addTests([unittest.makeSuite(ElementTreeC14NTest)])
5148 suite.addTests([unittest.makeSuite(ElementTreeElementSlicingTest)])
5149 if cElementTree:
5150 suite.addTests([unittest.makeSuite(CElementTreeTestCase)])
5151 suite.addTests([unittest.makeSuite(CElementTreeElementSlicingTest)])
5152 return suite
5153
5154 if __name__ == '__main__':
5155 print('to test use test.py %s' % __file__)
5156
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Aug 12 02:25:42 2019 | http://epydoc.sourceforge.net |