1
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)
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
65
66 try:
67 HelperTestCase.assertRegex
68 except AttributeError:
70 return self.assertRegexpMatches(*args, **kwargs)
71
72 @et_needs_pyversion(3, 6)
74
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
120
121 element = self.etree.Element("tag", key="value")
122
123
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
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
158
159
160
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
182
183
193
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
279
280 - def test_text(self):
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
288 - def test_text_empty(self):
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
296 - def test_text_other(self):
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
331 Element = self.etree.Element
332
333 class strTest(str):
334 pass
335
336 a = Element("a")
337 a.text = strTest("text")
338 self.assertXML(_bytes('<a>text</a>'),
339 a)
340
352
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
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
401
411
422
433
444
455
466
476
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
519
526
530
534
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
619
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
654
663
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
719
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
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
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
833
834 required_versions_ET['test_fromstringlist'] = (1,3)
842
843 required_versions_ET['test_fromstringlist_characters'] = (1,3)
850
851 required_versions_ET['test_fromstringlist_single'] = (1,3)
858
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
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
916
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
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)
967 - def test_itertext(self):
968
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
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
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)
1005 def summarize_list(l):
1006 return [el.tag for el in l]
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")),
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
1055
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
1093
1102
1116
1117 required_versions_ET['test_write_method_html'] = (1,3)
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
1167
1168
1169
1178
1179
1191
1214
1215 - def test_set_text(self):
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
1229 - def test_set_text2(self):
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
1280
1290
1302
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
1349
1350
1351 required_versions_ET['test_comment_text'] = (1,3)
1372
1373
1374 required_versions_ET['test_comment_whitespace'] = (1,3)
1387
1399
1411
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
1433 for i in pi:
1434 pass
1435
1451
1469
1479
1488
1503
1520
1538
1557
1563
1564 a = Element("a")
1565 a.tag = strTest("TAG")
1566 self.assertXML(_bytes('<TAG></TAG>'),
1567 a)
1568
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
1648
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')
1683
1684
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
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
1745
1772
1774
1775 Element = self.etree.Element
1776 SubElement = self.etree.SubElement
1777
1778
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
1820
1837
1852
1868
1884
1895
1908
1922
1944
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
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
2036
2057
2071
2096
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
2145
2146
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
2295
2310
2325
2340
2355
2370
2385
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
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
2453
2469
2484
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
2610
2627
2644
2661
2674
2684
2700
2719
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
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
2815
2816 del one, baz
2817 self.assertEqual('{http://a.b.c}baz', two[0].tag)
2818
2828
2838
2849
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
2895
2911
2929
2930 required_versions_ET['test_register_namespace'] = (1,3)
2948
2960
2974
2988
2989 required_versions_ET['test_tostring_method_html'] = (1,3)
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
3045
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
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
3165
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
3196
3200
3204
3205 required_versions_ET['test_parse_error'] = (1,3)
3207
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)
3220
3230
3240
3248
3255
3264
3277
3285
3295
3312
3313 required_versions_ET['test_parse_encoding_8bit_explicit'] = (1,3)
3328
3329 required_versions_ET['test_parse_encoding_8bit_override'] = (1,3)
3346
3348
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
3368
3377
3386
3397
3409
3422
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
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
3557
3569
3582
3583
3596
3598
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
3631
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
3658
3671
3681
3691
3701
3708
3709
3710
3726
3741
3742 required_versions_ET['test_feed_parser_error_close_empty'] = (1,3)
3747
3748 required_versions_ET['test_feed_parser_error_close_incomplete'] = (1,3)
3757
3758 required_versions_ET['test_feed_parser_error_broken'] = (1,3)
3772
3773 required_versions_ET['test_feed_parser_error_position'] = (1,3)
3785
3786
3787
3788 required_versions_ET['test_parser_target_property'] = (1,3)
3790 class Target(object):
3791 pass
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
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
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
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
4009 events = []
4010 class Target(object):
4011 def __init__(self):
4012 self._data = []
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)
4049 events = []
4050 class Target(object):
4051 def __init__(self):
4052 self._data = []
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)
4079 class Builder(list):
4080 def start(self, tag, attrib):
4081 self.append(("start", tag))
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)
4123 class Builder(list):
4124 def end_ns(self, prefix):
4125 self.append(("end-ns", prefix))
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
4175
4176 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4186
4187
4188
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
4216
4217
4218
4220
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)
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
4291
4297
4309
4310 - def assertXML(self, expected, element, encoding='us-ascii'):
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
4334
4337
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
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
4531
4532 - def _feed(self, parser, data, chunk_size=None):
4538
4540 self.assertEqual(
4541 [(event, (elem.tag, elem.text))
4542 for event, elem in islice(parser.read_events(), max_events)],
4543 expected)
4544
4546 self.assertEqual(
4547 list(islice(parser.read_events(), max_events)),
4548 expected)
4549
4554
4556 for chunk_size in (None, 1, 5):
4557
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)
4765
4766 @et_needs_pyversion(3, 8, 0, 'alpha', 4)
4775
4777
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
4808 - def subTest(self, name, **kwargs):
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
4822
4825
4827 c14n_roundtrip = self.c14n_roundtrip
4828
4829 self.assertEqual(c14n_roundtrip("<doc/>"), '<doc></doc>')
4830 self.assertEqual(c14n_roundtrip("<doc xmlns='uri'/>"),
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
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
4856
4857
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
4935
4936
4937
4938
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
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
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'
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
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
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
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:
5090 etree = ElementTree
5091
5092 @classmethod
5094 import warnings
5095
5096 warnings.filterwarnings(
5097 'ignore',
5098 r'This method will be removed.*\.iter\(\).*instead',
5099 PendingDeprecationWarning)
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
5153
5154 if __name__ == '__main__':
5155 print('to test use test.py %s' % __file__)
5156