| Home | Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf-8 -*-
2
3 """
4 Tests specific to the extended etree API
5
6 Tests that apply to the general ElementTree API should go into
7 test_elementtree
8 """
9
10 import os.path
11 import unittest
12 import copy
13 import sys
14 import re
15 import gc
16 import operator
17 import tempfile
18 import gzip
19
20 this_dir = os.path.dirname(__file__)
21 if this_dir not in sys.path:
22 sys.path.insert(0, this_dir) # needed for Py3
23
24 from common_imports import etree, StringIO, BytesIO, HelperTestCase, fileInTestDir, read_file
25 from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest
26 from common_imports import canonicalize, sorted, _str, _bytes
27
28 print("")
29 print("TESTED VERSION: %s" % etree.__version__)
30 print(" Python: " + repr(sys.version_info))
31 print(" lxml.etree: " + repr(etree.LXML_VERSION))
32 print(" libxml used: " + repr(etree.LIBXML_VERSION))
33 print(" libxml compiled: " + repr(etree.LIBXML_COMPILED_VERSION))
34 print(" libxslt used: " + repr(etree.LIBXSLT_VERSION))
35 print(" libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION))
36 print("")
37
38 try:
39 _unicode = unicode
40 except NameError:
41 # Python 3
42 _unicode = str
43
45 """Tests only for etree, not ElementTree"""
46 etree = etree
47
49 self.assertTrue(isinstance(etree.__version__, _unicode))
50 self.assertTrue(isinstance(etree.LXML_VERSION, tuple))
51 self.assertEqual(len(etree.LXML_VERSION), 4)
52 self.assertTrue(isinstance(etree.LXML_VERSION[0], int))
53 self.assertTrue(isinstance(etree.LXML_VERSION[1], int))
54 self.assertTrue(isinstance(etree.LXML_VERSION[2], int))
55 self.assertTrue(isinstance(etree.LXML_VERSION[3], int))
56 self.assertTrue(etree.__version__.startswith(
57 str(etree.LXML_VERSION[0])))
58
60 if hasattr(self.etree, '__pyx_capi__'):
61 # newer Pyrex compatible C-API
62 self.assertTrue(isinstance(self.etree.__pyx_capi__, dict))
63 self.assertTrue(len(self.etree.__pyx_capi__) > 0)
64 else:
65 # older C-API mechanism
66 self.assertTrue(hasattr(self.etree, '_import_c_api'))
67
69 Element = self.etree.Element
70 el = Element('name')
71 self.assertEqual(el.tag, 'name')
72 el = Element('{}name')
73 self.assertEqual(el.tag, 'name')
74
76 Element = self.etree.Element
77 el = Element('name')
78 self.assertRaises(ValueError, Element, '{}')
79 self.assertRaises(ValueError, setattr, el, 'tag', '{}')
80
81 self.assertRaises(ValueError, Element, '{test}')
82 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
83
85 Element = self.etree.Element
86 self.assertRaises(ValueError, Element, 'p:name')
87 self.assertRaises(ValueError, Element, '{test}p:name')
88
89 el = Element('name')
90 self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
91
93 Element = self.etree.Element
94 self.assertRaises(ValueError, Element, "p'name")
95 self.assertRaises(ValueError, Element, 'p"name')
96
97 self.assertRaises(ValueError, Element, "{test}p'name")
98 self.assertRaises(ValueError, Element, '{test}p"name')
99
100 el = Element('name')
101 self.assertRaises(ValueError, setattr, el, 'tag', "p'name")
102 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
103
105 Element = self.etree.Element
106 self.assertRaises(ValueError, Element, ' name ')
107 self.assertRaises(ValueError, Element, 'na me')
108 self.assertRaises(ValueError, Element, '{test} name')
109
110 el = Element('name')
111 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
112
114 Element = self.etree.Element
115 SubElement = self.etree.SubElement
116
117 el = Element('name')
118 self.assertRaises(ValueError, SubElement, el, '{}')
119 self.assertRaises(ValueError, SubElement, el, '{test}')
120
122 Element = self.etree.Element
123 SubElement = self.etree.SubElement
124
125 el = Element('name')
126 self.assertRaises(ValueError, SubElement, el, 'p:name')
127 self.assertRaises(ValueError, SubElement, el, '{test}p:name')
128
130 Element = self.etree.Element
131 SubElement = self.etree.SubElement
132
133 el = Element('name')
134 self.assertRaises(ValueError, SubElement, el, "p'name")
135 self.assertRaises(ValueError, SubElement, el, "{test}p'name")
136
137 self.assertRaises(ValueError, SubElement, el, 'p"name')
138 self.assertRaises(ValueError, SubElement, el, '{test}p"name')
139
141 Element = self.etree.Element
142 SubElement = self.etree.SubElement
143
144 el = Element('name')
145 self.assertRaises(ValueError, SubElement, el, ' name ')
146 self.assertRaises(ValueError, SubElement, el, 'na me')
147 self.assertRaises(ValueError, SubElement, el, '{test} name')
148
150 Element = self.etree.Element
151 SubElement = self.etree.SubElement
152
153 el = Element('name')
154 self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'})
155 self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'})
156 self.assertEqual(0, len(el))
157
159 QName = self.etree.QName
160 self.assertRaises(ValueError, QName, '')
161 self.assertRaises(ValueError, QName, 'test', '')
162
164 QName = self.etree.QName
165 self.assertRaises(ValueError, QName, 'p:name')
166 self.assertRaises(ValueError, QName, 'test', 'p:name')
167
169 QName = self.etree.QName
170 self.assertRaises(ValueError, QName, ' name ')
171 self.assertRaises(ValueError, QName, 'na me')
172 self.assertRaises(ValueError, QName, 'test', ' name')
173
175 # ET doesn't have namespace/localname properties on QNames
176 QName = self.etree.QName
177 namespace, localname = 'http://myns', 'a'
178 qname = QName(namespace, localname)
179 self.assertEqual(namespace, qname.namespace)
180 self.assertEqual(localname, qname.localname)
181
183 # ET doesn't have namespace/localname properties on QNames
184 QName = self.etree.QName
185 qname1 = QName('http://myns', 'a')
186 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'})
187
188 qname2 = QName(a)
189 self.assertEqual(a.tag, qname1.text)
190 self.assertEqual(qname1.text, qname2.text)
191 self.assertEqual(qname1, qname2)
192
194 # ET doesn't resove QNames as text values
195 etree = self.etree
196 qname = etree.QName('http://myns', 'a')
197 a = etree.Element(qname, nsmap={'p' : 'http://myns'})
198 a.text = qname
199
200 self.assertEqual("p:a", a.text)
201
203 etree = self.etree
204 self.assertRaises(ValueError,
205 etree.Element, "root", nsmap={'"' : 'testns'})
206 self.assertRaises(ValueError,
207 etree.Element, "root", nsmap={'&' : 'testns'})
208 self.assertRaises(ValueError,
209 etree.Element, "root", nsmap={'a:b' : 'testns'})
210
212 # ET in Py 3.x has no "attrib.has_key()" method
213 XML = self.etree.XML
214
215 root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
216 self.assertEqual(
217 True, root.attrib.has_key('bar'))
218 self.assertEqual(
219 False, root.attrib.has_key('baz'))
220 self.assertEqual(
221 False, root.attrib.has_key('hah'))
222 self.assertEqual(
223 True,
224 root.attrib.has_key('{http://ns.codespeak.net/test}baz'))
225
227 Element = self.etree.Element
228 root = Element("root")
229 root.set("attr", "TEST")
230 self.assertEqual("TEST", root.get("attr"))
231
233 # ElementTree accepts arbitrary attribute values
234 # lxml.etree allows only strings
235 Element = self.etree.Element
236 root = Element("root")
237 self.assertRaises(TypeError, root.set, "newattr", 5)
238 self.assertRaises(TypeError, root.set, "newattr", None)
239
241 XML = self.etree.XML
242 xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>')
243
244 root = XML(xml)
245 self.etree.strip_attributes(root, 'a')
246 self.assertEqual(_bytes('<test b="10" c="20"><x b="2"></x></test>'),
247 self._writeElement(root))
248
249 root = XML(xml)
250 self.etree.strip_attributes(root, 'b', 'c')
251 self.assertEqual(_bytes('<test a="5"><x a="4"></x></test>'),
252 self._writeElement(root))
253
255 XML = self.etree.XML
256 xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>')
257
258 root = XML(xml)
259 self.etree.strip_attributes(root, 'a')
260 self.assertEqual(
261 _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'),
262 self._writeElement(root))
263
264 root = XML(xml)
265 self.etree.strip_attributes(root, '{http://test/ns}a', 'c')
266 self.assertEqual(
267 _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'),
268 self._writeElement(root))
269
270 root = XML(xml)
271 self.etree.strip_attributes(root, '{http://test/ns}*')
272 self.assertEqual(
273 _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'),
274 self._writeElement(root))
275
277 XML = self.etree.XML
278 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>')
279
280 root = XML(xml)
281 self.etree.strip_elements(root, 'a')
282 self.assertEqual(_bytes('<test><x></x></test>'),
283 self._writeElement(root))
284
285 root = XML(xml)
286 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z')
287 self.assertEqual(_bytes('<test><a></a><x><a></a></x></test>'),
288 self._writeElement(root))
289
290 root = XML(xml)
291 self.etree.strip_elements(root, 'c')
292 self.assertEqual(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'),
293 self._writeElement(root))
294
296 XML = self.etree.XML
297 xml = _bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"/>C</b>BT</n:a>AT<x>X<a>A<b xmlns="urn:a"/>BT<c xmlns="urn:x"/>CT</a>AT</x>XT</test>')
298
299 root = XML(xml)
300 self.etree.strip_elements(root, 'a')
301 self.assertEqual(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X</x>XT</test>'),
302 self._writeElement(root))
303
304 root = XML(xml)
305 self.etree.strip_elements(root, '{urn:a}b', 'c')
306 self.assertEqual(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
307 self._writeElement(root))
308
309 root = XML(xml)
310 self.etree.strip_elements(root, '{urn:a}*', 'c')
311 self.assertEqual(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
312 self._writeElement(root))
313
314 root = XML(xml)
315 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False)
316 self.assertEqual(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
317 self._writeElement(root))
318
337
363
390
416
435
448
450 # lxml.etree separates target and text
451 Element = self.etree.Element
452 SubElement = self.etree.SubElement
453 ProcessingInstruction = self.etree.ProcessingInstruction
454
455 a = Element('a')
456 a.append(ProcessingInstruction('foo', 'some more text'))
457 self.assertEqual(a[0].target, 'foo')
458 self.assertEqual(a[0].text, 'some more text')
459
461 XML = self.etree.XML
462 root = XML(_bytes("<test><?mypi my test ?></test>"))
463 self.assertEqual(root[0].target, "mypi")
464 self.assertEqual(root[0].text, "my test ")
465
467 XML = self.etree.XML
468 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
469 self.assertEqual(root[0].target, "mypi")
470 self.assertEqual(root[0].get('my'), "1")
471 self.assertEqual(root[0].get('test'), " abc ")
472 self.assertEqual(root[0].get('quotes'), "' '")
473 self.assertEqual(root[0].get('only'), None)
474 self.assertEqual(root[0].get('names'), None)
475 self.assertEqual(root[0].get('nope'), None)
476
478 XML = self.etree.XML
479 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
480 self.assertEqual(root[0].target, "mypi")
481 self.assertEqual(root[0].attrib['my'], "1")
482 self.assertEqual(root[0].attrib['test'], " abc ")
483 self.assertEqual(root[0].attrib['quotes'], "' '")
484 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only')
485 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names')
486 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
487
489 # previously caused a crash
490 ProcessingInstruction = self.etree.ProcessingInstruction
491
492 a = ProcessingInstruction("PI", "ONE")
493 b = copy.deepcopy(a)
494 b.text = "ANOTHER"
495
496 self.assertEqual('ONE', a.text)
497 self.assertEqual('ANOTHER', b.text)
498
500 XML = self.etree.XML
501 tostring = self.etree.tostring
502 root = XML(_bytes("<?mypi my test ?><test/><!--comment -->"))
503 tree1 = self.etree.ElementTree(root)
504 self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"),
505 tostring(tree1))
506
507 tree2 = copy.deepcopy(tree1)
508 self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"),
509 tostring(tree2))
510
511 root2 = copy.deepcopy(tree1.getroot())
512 self.assertEqual(_bytes("<test/>"),
513 tostring(root2))
514
516 XML = self.etree.XML
517 tostring = self.etree.tostring
518 xml = _bytes('<!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>')
519 root = XML(xml)
520 tree1 = self.etree.ElementTree(root)
521 self.assertEqual(xml, tostring(tree1))
522
523 tree2 = copy.deepcopy(tree1)
524 self.assertEqual(xml, tostring(tree2))
525
526 root2 = copy.deepcopy(tree1.getroot())
527 self.assertEqual(_bytes("<test/>"),
528 tostring(root2))
529
531 # ElementTree accepts arbitrary attribute values
532 # lxml.etree allows only strings
533 Element = self.etree.Element
534
535 root = Element("root")
536 root.set("attr", "TEST")
537 self.assertEqual("TEST", root.get("attr"))
538 self.assertRaises(TypeError, root.set, "newattr", 5)
539
541 fromstring = self.etree.fromstring
542 tostring = self.etree.tostring
543 XMLParser = self.etree.XMLParser
544
545 xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
546 parser = XMLParser(remove_comments=True)
547 root = fromstring(xml, parser)
548 self.assertEqual(
549 _bytes('<a><b><c/></b></a>'),
550 tostring(root))
551
553 parse = self.etree.parse
554 tostring = self.etree.tostring
555 XMLParser = self.etree.XMLParser
556
557 xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>')
558
559 f = BytesIO(xml)
560 tree = parse(f)
561 self.assertEqual(
562 xml,
563 tostring(tree))
564
565 parser = XMLParser(remove_pis=True)
566 tree = parse(f, parser)
567 self.assertEqual(
568 _bytes('<a><b><c/></b></a>'),
569 tostring(tree))
570
572 # ET raises IOError only
573 parse = self.etree.parse
574 self.assertRaises(TypeError, parse, 'notthere.xml', object())
575
577 # ET removes comments
578 iterparse = self.etree.iterparse
579 tostring = self.etree.tostring
580
581 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
582 events = list(iterparse(f))
583 root = events[-1][1]
584 self.assertEqual(3, len(events))
585 self.assertEqual(
586 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
587 tostring(root))
588
590 # ET removes comments
591 iterparse = self.etree.iterparse
592 tostring = self.etree.tostring
593
594 def name(event, el):
595 if event == 'comment':
596 return el.text
597 else:
598 return el.tag
599
600 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
601 events = list(iterparse(f, events=('end', 'comment')))
602 root = events[-1][1]
603 self.assertEqual(6, len(events))
604 self.assertEqual(['A', ' B ', 'c', 'b', 'C', 'a'],
605 [ name(*item) for item in events ])
606 self.assertEqual(
607 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
608 tostring(root))
609
611 # ET removes pis
612 iterparse = self.etree.iterparse
613 tostring = self.etree.tostring
614 ElementTree = self.etree.ElementTree
615
616 def name(event, el):
617 if event == 'pi':
618 return (el.target, el.text)
619 else:
620 return el.tag
621
622 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>')
623 events = list(iterparse(f, events=('end', 'pi')))
624 root = events[-2][1]
625 self.assertEqual(8, len(events))
626 self.assertEqual([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b',
627 ('pid','d'), 'a', ('pie','e')],
628 [ name(*item) for item in events ])
629 self.assertEqual(
630 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'),
631 tostring(ElementTree(root)))
632
634 iterparse = self.etree.iterparse
635 tostring = self.etree.tostring
636
637 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
638 events = list(iterparse(f, remove_comments=True,
639 events=('end', 'comment')))
640 root = events[-1][1]
641 self.assertEqual(3, len(events))
642 self.assertEqual(['c', 'b', 'a'],
643 [ el.tag for (event, el) in events ])
644 self.assertEqual(
645 _bytes('<a><b><c/></b></a>'),
646 tostring(root))
647
649 iterparse = self.etree.iterparse
650 f = BytesIO('<a><b><c/></a>')
651 # ET raises ExpatError, lxml raises XMLSyntaxError
652 self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
653
655 iterparse = self.etree.iterparse
656 f = BytesIO("""
657 <a> \n \n <b> b test </b> \n
658
659 \n\t <c> \n </c> </a> \n """)
660 iterator = iterparse(f, remove_blank_text=True)
661 text = [ (element.text, element.tail)
662 for event, element in iterator ]
663 self.assertEqual(
664 [(" b test ", None), (" \n ", None), (None, None)],
665 text)
666
668 iterparse = self.etree.iterparse
669 f = BytesIO('<a><b><d/></b><c/></a>')
670
671 iterator = iterparse(f, tag="b", events=('start', 'end'))
672 events = list(iterator)
673 root = iterator.root
674 self.assertEqual(
675 [('start', root[0]), ('end', root[0])],
676 events)
677
679 iterparse = self.etree.iterparse
680 f = BytesIO('<a><b><d/></b><c/></a>')
681
682 iterator = iterparse(f, tag="*", events=('start', 'end'))
683 events = list(iterator)
684 self.assertEqual(
685 8,
686 len(events))
687
689 iterparse = self.etree.iterparse
690 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
691
692 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end'))
693 events = list(iterator)
694 root = iterator.root
695 self.assertEqual(
696 [('start', root[0]), ('end', root[0])],
697 events)
698
700 iterparse = self.etree.iterparse
701 f = BytesIO('<a><b><d/></b><c/></a>')
702 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
703 events = list(iterator)
704 root = iterator.root
705 self.assertEqual(
706 [('start', root[0]), ('end', root[0])],
707 events)
708
709 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
710 iterator = iterparse(f, tag="{}b", events=('start', 'end'))
711 events = list(iterator)
712 root = iterator.root
713 self.assertEqual([], events)
714
716 iterparse = self.etree.iterparse
717 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
718 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end'))
719 events = list(iterator)
720 self.assertEqual(8, len(events))
721
723 iterparse = self.etree.iterparse
724 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
725 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
726 events = list(iterator)
727 self.assertEqual([], events)
728
729 f = BytesIO('<a><b><d/></b><c/></a>')
730 iterator = iterparse(f, tag="{}*", events=('start', 'end'))
731 events = list(iterator)
732 self.assertEqual(8, len(events))
733
735 text = _str('Søk på nettet')
736 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
737 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
738 ).encode('iso-8859-1')
739
740 self.assertRaises(self.etree.ParseError,
741 list, self.etree.iterparse(BytesIO(xml_latin1)))
742
744 text = _str('Søk på nettet', encoding="UTF-8")
745 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
746 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
747 ).encode('iso-8859-1')
748
749 iterator = self.etree.iterparse(BytesIO(xml_latin1),
750 encoding="iso-8859-1")
751 self.assertEqual(1, len(list(iterator)))
752
753 a = iterator.root
754 self.assertEqual(a.text, text)
755
757 tostring = self.etree.tostring
758 f = BytesIO('<root><![CDATA[test]]></root>')
759 context = self.etree.iterparse(f, strip_cdata=False)
760 content = [ el.text for event,el in context ]
761
762 self.assertEqual(['test'], content)
763 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
764 tostring(context.root))
765
769
771 self.etree.XMLParser(encoding="ascii")
772 self.etree.XMLParser(encoding="utf-8")
773 self.etree.XMLParser(encoding="iso-8859-1")
774
776 parser = self.etree.XMLParser(recover=True)
777
778 parser.feed('<?xml version=')
779 parser.feed('"1.0"?><ro')
780 parser.feed('ot><')
781 parser.feed('a test="works"')
782 parser.feed('><othertag/></root') # <a> not closed!
783 parser.feed('>')
784
785 root = parser.close()
786
787 self.assertEqual(root.tag, "root")
788 self.assertEqual(len(root), 1)
789 self.assertEqual(root[0].tag, "a")
790 self.assertEqual(root[0].get("test"), "works")
791 self.assertEqual(len(root[0]), 1)
792 self.assertEqual(root[0][0].tag, "othertag")
793 # FIXME: would be nice to get some errors logged ...
794 #self.assertTrue(len(parser.error_log) > 0, "error log is empty")
795
797 assertEqual = self.assertEqual
798 assertFalse = self.assertFalse
799
800 events = []
801 class Target(object):
802 def start(self, tag, attrib):
803 events.append("start")
804 assertFalse(attrib)
805 assertEqual("TAG", tag)
806 def end(self, tag):
807 events.append("end")
808 assertEqual("TAG", tag)
809 def close(self):
810 return "DONE" # no Element!
811
812 parser = self.etree.XMLParser(target=Target())
813 tree = self.etree.ElementTree()
814
815 self.assertRaises(TypeError,
816 tree.parse, BytesIO("<TAG/>"), parser=parser)
817 self.assertEqual(["start", "end"], events)
818
820 # ET doesn't call .close() on errors
821 events = []
822 class Target(object):
823 def start(self, tag, attrib):
824 events.append("start-" + tag)
825 def end(self, tag):
826 events.append("end-" + tag)
827 if tag == 'a':
828 raise ValueError("dead and gone")
829 def data(self, data):
830 events.append("data-" + data)
831 def close(self):
832 events.append("close")
833 return "DONE"
834
835 parser = self.etree.XMLParser(target=Target())
836
837 try:
838 parser.feed(_bytes('<root>A<a>ca</a>B</root>'))
839 done = parser.close()
840 self.fail("error expected, but parsing succeeded")
841 except ValueError:
842 done = 'value error received as expected'
843
844 self.assertEqual(["start-root", "data-A", "start-a",
845 "data-ca", "end-a", "close"],
846 events)
847
849 # ET doesn't call .close() on errors
850 events = []
851 class Target(object):
852 def start(self, tag, attrib):
853 events.append("start-" + tag)
854 def end(self, tag):
855 events.append("end-" + tag)
856 if tag == 'a':
857 raise ValueError("dead and gone")
858 def data(self, data):
859 events.append("data-" + data)
860 def close(self):
861 events.append("close")
862 return "DONE"
863
864 parser = self.etree.XMLParser(target=Target())
865
866 try:
867 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'),
868 parser=parser)
869 self.fail("error expected, but parsing succeeded")
870 except ValueError:
871 done = 'value error received as expected'
872
873 self.assertEqual(["start-root", "data-A", "start-a",
874 "data-ca", "end-a", "close"],
875 events)
876
878 events = []
879 class Target(object):
880 def start(self, tag, attrib):
881 events.append("start-" + tag)
882 def end(self, tag):
883 events.append("end-" + tag)
884 def data(self, data):
885 events.append("data-" + data)
886 def comment(self, text):
887 events.append("comment-" + text)
888 def close(self):
889 return "DONE"
890
891 parser = self.etree.XMLParser(target=Target())
892
893 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->'))
894 done = parser.close()
895
896 self.assertEqual("DONE", done)
897 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b",
898 "start-sub", "end-sub", "comment-c", "data-B",
899 "end-root", "comment-d"],
900 events)
901
903 events = []
904 class Target(object):
905 def start(self, tag, attrib):
906 events.append("start-" + tag)
907 def end(self, tag):
908 events.append("end-" + tag)
909 def data(self, data):
910 events.append("data-" + data)
911 def pi(self, target, data):
912 events.append("pi-" + target + "-" + data)
913 def close(self):
914 return "DONE"
915
916 parser = self.etree.XMLParser(target=Target())
917
918 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>'))
919 done = parser.close()
920
921 self.assertEqual("DONE", done)
922 self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b",
923 "data-B", "end-root", "pi-test-c"],
924 events)
925
927 events = []
928 class Target(object):
929 def start(self, tag, attrib):
930 events.append("start-" + tag)
931 def end(self, tag):
932 events.append("end-" + tag)
933 def data(self, data):
934 events.append("data-" + data)
935 def close(self):
936 return "DONE"
937
938 parser = self.etree.XMLParser(target=Target(),
939 strip_cdata=False)
940
941 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>'))
942 done = parser.close()
943
944 self.assertEqual("DONE", done)
945 self.assertEqual(["start-root", "data-A", "start-a",
946 "data-ca", "end-a", "data-B", "end-root"],
947 events)
948
950 events = []
951 class Target(object):
952 def start(self, tag, attrib):
953 events.append("start-" + tag)
954 def end(self, tag):
955 events.append("end-" + tag)
956 def data(self, data):
957 events.append("data-" + data)
958 def close(self):
959 events.append("close")
960 return "DONE"
961
962 parser = self.etree.XMLParser(target=Target(),
963 recover=True)
964
965 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>'))
966 done = parser.close()
967
968 self.assertEqual("DONE", done)
969 self.assertEqual(["start-root", "data-A", "start-a",
970 "data-ca", "end-a", "data-B",
971 "end-root", "close"],
972 events)
973
975 iterwalk = self.etree.iterwalk
976 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
977
978 iterator = iterwalk(root, tag="b", events=('start', 'end'))
979 events = list(iterator)
980 self.assertEqual(
981 [('start', root[0]), ('end', root[0])],
982 events)
983
985 iterwalk = self.etree.iterwalk
986 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
987
988 iterator = iterwalk(root, tag="*", events=('start', 'end'))
989 events = list(iterator)
990 self.assertEqual(
991 8,
992 len(events))
993
995 iterwalk = self.etree.iterwalk
996 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
997
998 events = list(iterwalk(root))
999 self.assertEqual(
1000 [('end', root[0]), ('end', root[1]), ('end', root)],
1001 events)
1002
1004 iterwalk = self.etree.iterwalk
1005 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1006
1007 iterator = iterwalk(root, events=('start',))
1008 events = list(iterator)
1009 self.assertEqual(
1010 [('start', root), ('start', root[0]), ('start', root[1])],
1011 events)
1012
1014 iterwalk = self.etree.iterwalk
1015 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1016
1017 iterator = iterwalk(root, events=('start','end'))
1018 events = list(iterator)
1019 self.assertEqual(
1020 [('start', root), ('start', root[0]), ('end', root[0]),
1021 ('start', root[1]), ('end', root[1]), ('end', root)],
1022 events)
1023
1025 iterwalk = self.etree.iterwalk
1026 root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
1027
1028 iterator = iterwalk(root)
1029 for event, elem in iterator:
1030 elem.clear()
1031
1032 self.assertEqual(0,
1033 len(root))
1034
1036 iterwalk = self.etree.iterwalk
1037 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
1038
1039 attr_name = '{testns}bla'
1040 events = []
1041 iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
1042 for event, elem in iterator:
1043 events.append(event)
1044 if event == 'start':
1045 if elem.tag != '{ns1}a':
1046 elem.set(attr_name, 'value')
1047
1048 self.assertEqual(
1049 ['start-ns', 'start', 'start', 'start-ns', 'start',
1050 'end', 'end-ns', 'end', 'end', 'end-ns'],
1051 events)
1052
1053 self.assertEqual(
1054 None,
1055 root.get(attr_name))
1056 self.assertEqual(
1057 'value',
1058 root[0].get(attr_name))
1059
1061 iterwalk = self.etree.iterwalk
1062 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
1063
1064 counts = []
1065 for event, elem in iterwalk(root):
1066 counts.append(len(list(elem.getiterator())))
1067 self.assertEqual(
1068 [1,2,1,4],
1069 counts)
1070
1072 parse = self.etree.parse
1073 parser = self.etree.XMLParser(dtd_validation=True)
1074 assertEqual = self.assertEqual
1075 test_url = _str("__nosuch.dtd")
1076
1077 class MyResolver(self.etree.Resolver):
1078 def resolve(self, url, id, context):
1079 assertEqual(url, test_url)
1080 return self.resolve_string(
1081 _str('''<!ENTITY myentity "%s">
1082 <!ELEMENT doc ANY>''') % url, context)
1083
1084 parser.resolvers.add(MyResolver())
1085
1086 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1087 tree = parse(StringIO(xml), parser)
1088 root = tree.getroot()
1089 self.assertEqual(root.text, test_url)
1090
1092 parse = self.etree.parse
1093 parser = self.etree.XMLParser(dtd_validation=True)
1094 assertEqual = self.assertEqual
1095 test_url = _str("__nosuch.dtd")
1096
1097 class MyResolver(self.etree.Resolver):
1098 def resolve(self, url, id, context):
1099 assertEqual(url, test_url)
1100 return self.resolve_string(
1101 (_str('''<!ENTITY myentity "%s">
1102 <!ELEMENT doc ANY>''') % url).encode('utf-8'),
1103 context)
1104
1105 parser.resolvers.add(MyResolver())
1106
1107 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1108 tree = parse(StringIO(xml), parser)
1109 root = tree.getroot()
1110 self.assertEqual(root.text, test_url)
1111
1113 parse = self.etree.parse
1114 parser = self.etree.XMLParser(dtd_validation=True)
1115 assertEqual = self.assertEqual
1116 test_url = _str("__nosuch.dtd")
1117
1118 class MyResolver(self.etree.Resolver):
1119 def resolve(self, url, id, context):
1120 assertEqual(url, test_url)
1121 return self.resolve_file(
1122 SillyFileLike(
1123 _str('''<!ENTITY myentity "%s">
1124 <!ELEMENT doc ANY>''') % url), context)
1125
1126 parser.resolvers.add(MyResolver())
1127
1128 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1129 tree = parse(StringIO(xml), parser)
1130 root = tree.getroot()
1131 self.assertEqual(root.text, test_url)
1132
1134 parse = self.etree.parse
1135 parser = self.etree.XMLParser(attribute_defaults=True)
1136 assertEqual = self.assertEqual
1137 test_url = _str("__nosuch.dtd")
1138
1139 class MyResolver(self.etree.Resolver):
1140 def resolve(self, url, id, context):
1141 assertEqual(url, test_url)
1142 return self.resolve_filename(
1143 fileInTestDir('test.dtd'), context)
1144
1145 parser.resolvers.add(MyResolver())
1146
1147 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1148 tree = parse(StringIO(xml), parser)
1149 root = tree.getroot()
1150 self.assertEqual(
1151 root.attrib, {'default': 'valueA'})
1152 self.assertEqual(
1153 root[0].attrib, {'default': 'valueB'})
1154
1156 parse = self.etree.parse
1157 parser = self.etree.XMLParser(attribute_defaults=True)
1158 assertEqual = self.assertEqual
1159 test_url = _str("__nosuch.dtd")
1160
1161 class MyResolver(self.etree.Resolver):
1162 def resolve(self, url, id, context):
1163 assertEqual(url, fileInTestDir(test_url))
1164 return self.resolve_filename(
1165 fileInTestDir('test.dtd'), context)
1166
1167 parser.resolvers.add(MyResolver())
1168
1169 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1170 tree = parse(StringIO(xml), parser,
1171 base_url=fileInTestDir('__test.xml'))
1172 root = tree.getroot()
1173 self.assertEqual(
1174 root.attrib, {'default': 'valueA'})
1175 self.assertEqual(
1176 root[0].attrib, {'default': 'valueB'})
1177
1179 parse = self.etree.parse
1180 parser = self.etree.XMLParser(attribute_defaults=True)
1181 assertEqual = self.assertEqual
1182 test_url = _str("__nosuch.dtd")
1183
1184 class MyResolver(self.etree.Resolver):
1185 def resolve(self, url, id, context):
1186 assertEqual(url, test_url)
1187 return self.resolve_file(
1188 open(fileInTestDir('test.dtd'), 'rb'), context)
1189
1190 parser.resolvers.add(MyResolver())
1191
1192 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
1193 tree = parse(StringIO(xml), parser)
1194 root = tree.getroot()
1195 self.assertEqual(
1196 root.attrib, {'default': 'valueA'})
1197 self.assertEqual(
1198 root[0].attrib, {'default': 'valueB'})
1199
1201 parse = self.etree.parse
1202 parser = self.etree.XMLParser(load_dtd=True)
1203 assertEqual = self.assertEqual
1204 test_url = _str("__nosuch.dtd")
1205
1206 class check(object):
1207 resolved = False
1208
1209 class MyResolver(self.etree.Resolver):
1210 def resolve(self, url, id, context):
1211 assertEqual(url, test_url)
1212 check.resolved = True
1213 return self.resolve_empty(context)
1214
1215 parser.resolvers.add(MyResolver())
1216
1217 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
1218 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
1219 self.assertTrue(check.resolved)
1220
1222 parse = self.etree.parse
1223 parser = self.etree.XMLParser(dtd_validation=True)
1224
1225 class _LocalException(Exception):
1226 pass
1227
1228 class MyResolver(self.etree.Resolver):
1229 def resolve(self, url, id, context):
1230 raise _LocalException
1231
1232 parser.resolvers.add(MyResolver())
1233
1234 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
1235 self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
1236
1237 if etree.LIBXML_VERSION > (2,6,20):
1239 parse = self.etree.parse
1240 tostring = self.etree.tostring
1241 parser = self.etree.XMLParser(resolve_entities=False)
1242 Entity = self.etree.Entity
1243
1244 xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>')
1245 tree = parse(BytesIO(xml), parser)
1246 root = tree.getroot()
1247 self.assertEqual(root[0].tag, Entity)
1248 self.assertEqual(root[0].text, "&myentity;")
1249 self.assertEqual(root[0].tail, None)
1250 self.assertEqual(root[0].name, "myentity")
1251
1252 self.assertEqual(_bytes('<doc>&myentity;</doc>'),
1253 tostring(root))
1254
1256 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]>
1257 <root>
1258 <child1/>
1259 <child2/>
1260 <child3> </child3>
1261 </root>''')
1262
1263 parser = self.etree.XMLParser(resolve_entities=False)
1264 root = etree.fromstring(xml, parser)
1265 self.assertEqual([ el.tag for el in root ],
1266 ['child1', 'child2', 'child3'])
1267
1268 root[0] = root[-1]
1269 self.assertEqual([ el.tag for el in root ],
1270 ['child3', 'child2'])
1271 self.assertEqual(root[0][0].text, ' ')
1272 self.assertEqual(root[0][0].name, 'nbsp')
1273
1275 Entity = self.etree.Entity
1276 Element = self.etree.Element
1277 tostring = self.etree.tostring
1278
1279 root = Element("root")
1280 root.append( Entity("test") )
1281
1282 self.assertEqual(root[0].tag, Entity)
1283 self.assertEqual(root[0].text, "&test;")
1284 self.assertEqual(root[0].tail, None)
1285 self.assertEqual(root[0].name, "test")
1286
1287 self.assertEqual(_bytes('<root>&test;</root>'),
1288 tostring(root))
1289
1291 Entity = self.etree.Entity
1292 self.assertEqual(Entity("test").text, '&test;')
1293 self.assertEqual(Entity("#17683").text, '䔓')
1294 self.assertEqual(Entity("#x1768").text, 'ᝨ')
1295 self.assertEqual(Entity("#x98AF").text, '颯')
1296
1298 Entity = self.etree.Entity
1299 self.assertRaises(ValueError, Entity, 'a b c')
1300 self.assertRaises(ValueError, Entity, 'a,b')
1301 self.assertRaises(ValueError, Entity, 'a\0b')
1302 self.assertRaises(ValueError, Entity, '#abc')
1303 self.assertRaises(ValueError, Entity, '#xxyz')
1304
1306 CDATA = self.etree.CDATA
1307 Element = self.etree.Element
1308 tostring = self.etree.tostring
1309
1310 root = Element("root")
1311 root.text = CDATA('test')
1312
1313 self.assertEqual('test',
1314 root.text)
1315 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1316 tostring(root))
1317
1319 CDATA = self.etree.CDATA
1320 Element = self.etree.Element
1321 root = Element("root")
1322
1323 root.text = CDATA("test")
1324 self.assertEqual('test', root.text)
1325
1326 root.text = CDATA(_str("test"))
1327 self.assertEqual('test', root.text)
1328
1329 self.assertRaises(TypeError, CDATA, 1)
1330
1332 CDATA = self.etree.CDATA
1333 Element = self.etree.Element
1334
1335 root = Element("root")
1336 cdata = CDATA('test')
1337
1338 self.assertRaises(TypeError,
1339 setattr, root, 'tail', cdata)
1340 self.assertRaises(TypeError,
1341 root.set, 'attr', cdata)
1342 self.assertRaises(TypeError,
1343 operator.setitem, root.attrib, 'attr', cdata)
1344
1346 tostring = self.etree.tostring
1347 parser = self.etree.XMLParser(strip_cdata=False)
1348 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1349
1350 self.assertEqual('test', root.text)
1351 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1352 tostring(root))
1353
1355 tostring = self.etree.tostring
1356 parser = self.etree.XMLParser(strip_cdata=False)
1357 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
1358 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'),
1359 tostring(root))
1360
1361 self.assertEqual(['test'], root.xpath('//text()'))
1362
1363 # TypeError in etree, AssertionError in ElementTree;
1365 Element = self.etree.Element
1366 SubElement = self.etree.SubElement
1367
1368 a = Element('a')
1369 b = SubElement(a, 'b')
1370
1371 self.assertRaises(TypeError,
1372 a.__setitem__, 0, 'foo')
1373
1375 Element = self.etree.Element
1376 root = Element('root')
1377 # raises AssertionError in ElementTree
1378 self.assertRaises(TypeError, root.append, None)
1379 self.assertRaises(TypeError, root.extend, [None])
1380 self.assertRaises(TypeError, root.extend, [Element('one'), None])
1381 self.assertEqual('one', root[0].tag)
1382
1384 Element = self.etree.Element
1385 SubElement = self.etree.SubElement
1386 root = Element('root')
1387 SubElement(root, 'a')
1388 SubElement(root, 'b')
1389
1390 self.assertEqual(['a', 'b'],
1391 [c.tag for c in root])
1392 root[1].addnext(root[0])
1393 self.assertEqual(['b', 'a'],
1394 [c.tag for c in root])
1395
1397 Element = self.etree.Element
1398 SubElement = self.etree.SubElement
1399 root = Element('root')
1400 SubElement(root, 'a')
1401 SubElement(root, 'b')
1402
1403 self.assertEqual(['a', 'b'],
1404 [c.tag for c in root])
1405 root[0].addprevious(root[1])
1406 self.assertEqual(['b', 'a'],
1407 [c.tag for c in root])
1408
1410 Element = self.etree.Element
1411 a = Element('a')
1412 b = Element('b')
1413 self.assertRaises(TypeError, a.addnext, b)
1414
1416 Element = self.etree.Element
1417 a = Element('a')
1418 b = Element('b')
1419 self.assertRaises(TypeError, a.addnext, b)
1420
1422 Element = self.etree.Element
1423 SubElement = self.etree.SubElement
1424 PI = self.etree.PI
1425 root = Element('root')
1426 SubElement(root, 'a')
1427 pi = PI('TARGET', 'TEXT')
1428 pi.tail = "TAIL"
1429
1430 self.assertEqual(_bytes('<root><a></a></root>'),
1431 self._writeElement(root))
1432 root[0].addprevious(pi)
1433 self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'),
1434 self._writeElement(root))
1435
1437 Element = self.etree.Element
1438 PI = self.etree.PI
1439 root = Element('root')
1440 pi = PI('TARGET', 'TEXT')
1441 pi.tail = "TAIL"
1442
1443 self.assertEqual(_bytes('<root></root>'),
1444 self._writeElement(root))
1445 root.addprevious(pi)
1446 self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'),
1447 self._writeElement(root))
1448
1450 Element = self.etree.Element
1451 SubElement = self.etree.SubElement
1452 PI = self.etree.PI
1453 root = Element('root')
1454 SubElement(root, 'a')
1455 pi = PI('TARGET', 'TEXT')
1456 pi.tail = "TAIL"
1457
1458 self.assertEqual(_bytes('<root><a></a></root>'),
1459 self._writeElement(root))
1460 root[0].addnext(pi)
1461 self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'),
1462 self._writeElement(root))
1463
1465 Element = self.etree.Element
1466 PI = self.etree.PI
1467 root = Element('root')
1468 pi = PI('TARGET', 'TEXT')
1469 pi.tail = "TAIL"
1470
1471 self.assertEqual(_bytes('<root></root>'),
1472 self._writeElement(root))
1473 root.addnext(pi)
1474 self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'),
1475 self._writeElement(root))
1476
1478 Element = self.etree.Element
1479 SubElement = self.etree.SubElement
1480 Comment = self.etree.Comment
1481 root = Element('root')
1482 SubElement(root, 'a')
1483 comment = Comment('TEXT ')
1484 comment.tail = "TAIL"
1485
1486 self.assertEqual(_bytes('<root><a></a></root>'),
1487 self._writeElement(root))
1488 root[0].addnext(comment)
1489 self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'),
1490 self._writeElement(root))
1491
1493 Element = self.etree.Element
1494 Comment = self.etree.Comment
1495 root = Element('root')
1496 comment = Comment('TEXT ')
1497 comment.tail = "TAIL"
1498
1499 self.assertEqual(_bytes('<root></root>'),
1500 self._writeElement(root))
1501 root.addnext(comment)
1502 self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'),
1503 self._writeElement(root))
1504
1506 Element = self.etree.Element
1507 SubElement = self.etree.SubElement
1508 Comment = self.etree.Comment
1509 root = Element('root')
1510 SubElement(root, 'a')
1511 comment = Comment('TEXT ')
1512 comment.tail = "TAIL"
1513
1514 self.assertEqual(_bytes('<root><a></a></root>'),
1515 self._writeElement(root))
1516 root[0].addprevious(comment)
1517 self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'),
1518 self._writeElement(root))
1519
1521 Element = self.etree.Element
1522 Comment = self.etree.Comment
1523 root = Element('root')
1524 comment = Comment('TEXT ')
1525 comment.tail = "TAIL"
1526
1527 self.assertEqual(_bytes('<root></root>'),
1528 self._writeElement(root))
1529 root.addprevious(comment)
1530 self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'),
1531 self._writeElement(root))
1532
1533 # ET's Elements have items() and key(), but not values()
1535 XML = self.etree.XML
1536
1537 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
1538 values = root.values()
1539 values.sort()
1540 self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
1541
1542 # gives error in ElementTree
1544 Element = self.etree.Element
1545 Comment = self.etree.Comment
1546
1547 a = Element('a')
1548 a.append(Comment())
1549 self.assertEqual(
1550 _bytes('<a><!----></a>'),
1551 self._writeElement(a))
1552
1553 # ElementTree ignores comments
1555 ElementTree = self.etree.ElementTree
1556 tostring = self.etree.tostring
1557
1558 xml = _bytes('<a><b/><!----><c/></a>')
1559 f = BytesIO(xml)
1560 doc = ElementTree(file=f)
1561 a = doc.getroot()
1562 self.assertEqual(
1563 '',
1564 a[1].text)
1565 self.assertEqual(
1566 xml,
1567 tostring(a))
1568
1569 # ElementTree ignores comments
1571 ElementTree = self.etree.ElementTree
1572
1573 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>')
1574 doc = ElementTree(file=f)
1575 a = doc.getroot()
1576 self.assertEqual(
1577 ' hoi ',
1578 a[1].text)
1579
1580 # does not raise an exception in ElementTree
1582 Element = self.etree.Element
1583 Comment = self.etree.Comment
1584
1585 c = Comment()
1586 el = Element('myel')
1587
1588 self.assertRaises(TypeError, c.append, el)
1589 self.assertRaises(TypeError, c.insert, 0, el)
1590 self.assertRaises(TypeError, c.set, "myattr", "test")
1591
1592 # test passing 'None' to dump
1595
1597 ElementTree = self.etree.ElementTree
1598
1599 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>')
1600 doc = ElementTree(file=f)
1601 a = doc.getroot()
1602 self.assertEqual(
1603 None,
1604 a.prefix)
1605 self.assertEqual(
1606 'foo',
1607 a[0].prefix)
1608
1610 ElementTree = self.etree.ElementTree
1611
1612 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>')
1613 doc = ElementTree(file=f)
1614 a = doc.getroot()
1615 self.assertEqual(
1616 None,
1617 a.prefix)
1618 self.assertEqual(
1619 None,
1620 a[0].prefix)
1621
1623 Element = self.etree.Element
1624 SubElement = self.etree.SubElement
1625
1626 a = Element('a')
1627 b = SubElement(a, 'b')
1628 c = SubElement(a, 'c')
1629 d = SubElement(b, 'd')
1630 self.assertEqual(
1631 None,
1632 a.getparent())
1633 self.assertEqual(
1634 a,
1635 b.getparent())
1636 self.assertEqual(
1637 b.getparent(),
1638 c.getparent())
1639 self.assertEqual(
1640 b,
1641 d.getparent())
1642
1644 XML = self.etree.XML
1645
1646 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
1647 result = []
1648 for el in root.iterchildren():
1649 result.append(el.tag)
1650 self.assertEqual(['one', 'two', 'three'], result)
1651
1653 XML = self.etree.XML
1654
1655 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
1656 result = []
1657 for el in root.iterchildren(reversed=True):
1658 result.append(el.tag)
1659 self.assertEqual(['three', 'two', 'one'], result)
1660
1662 XML = self.etree.XML
1663
1664 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
1665 result = []
1666 for el in root.iterchildren(tag='two'):
1667 result.append(el.text)
1668 self.assertEqual(['Two', 'Bla'], result)
1669
1671 XML = self.etree.XML
1672
1673 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
1674 result = []
1675 for el in root.iterchildren(reversed=True, tag='two'):
1676 result.append(el.text)
1677 self.assertEqual(['Bla', 'Two'], result)
1678
1680 XML = self.etree.XML
1681
1682 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1683 result = []
1684 for el in root.iterchildren(tag=['two', 'three']):
1685 result.append(el.text)
1686 self.assertEqual(['Two', 'Bla', None], result)
1687
1689 XML = self.etree.XML
1690
1691 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
1692 result = []
1693 for el in root.iterchildren(reversed=True, tag=['two', 'three']):
1694 result.append(el.text)
1695 self.assertEqual([None, 'Bla', 'Two'], result)
1696
1698 Element = self.etree.Element
1699 SubElement = self.etree.SubElement
1700
1701 a = Element('a')
1702 b = SubElement(a, 'b')
1703 c = SubElement(a, 'c')
1704 d = SubElement(b, 'd')
1705 self.assertEqual(
1706 [],
1707 list(a.iterancestors()))
1708 self.assertEqual(
1709 [a],
1710 list(b.iterancestors()))
1711 self.assertEqual(
1712 [a],
1713 list(c.iterancestors()))
1714 self.assertEqual(
1715 [b, a],
1716 list(d.iterancestors()))
1717
1719 Element = self.etree.Element
1720 SubElement = self.etree.SubElement
1721
1722 a = Element('a')
1723 b = SubElement(a, 'b')
1724 c = SubElement(a, 'c')
1725 d = SubElement(b, 'd')
1726 self.assertEqual(
1727 [a],
1728 list(d.iterancestors(tag='a')))
1729 self.assertEqual(
1730 [b, a],
1731 list(d.iterancestors(tag='*')))
1732
1734 Element = self.etree.Element
1735 SubElement = self.etree.SubElement
1736
1737 a = Element('a')
1738 b = SubElement(a, 'b')
1739 c = SubElement(a, 'c')
1740 d = SubElement(b, 'd')
1741 self.assertEqual(
1742 [b, a],
1743 list(d.iterancestors(tag=('a', 'b'))))
1744 self.assertEqual(
1745 [],
1746 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
1747 self.assertEqual(
1748 [],
1749 list(d.iterancestors(tag=('d', 'x'))))
1750 self.assertEqual(
1751 [b, a],
1752 list(d.iterancestors(tag=('b', '*'))))
1753 self.assertEqual(
1754 [b],
1755 list(d.iterancestors(tag=('b', 'c'))))
1756
1758 Element = self.etree.Element
1759 SubElement = self.etree.SubElement
1760
1761 a = Element('a')
1762 b = SubElement(a, 'b')
1763 c = SubElement(a, 'c')
1764 d = SubElement(b, 'd')
1765 e = SubElement(c, 'e')
1766
1767 self.assertEqual(
1768 [b, d, c, e],
1769 list(a.iterdescendants()))
1770 self.assertEqual(
1771 [],
1772 list(d.iterdescendants()))
1773
1775 Element = self.etree.Element
1776 SubElement = self.etree.SubElement
1777
1778 a = Element('a')
1779 b = SubElement(a, 'b')
1780 c = SubElement(a, 'c')
1781 d = SubElement(b, 'd')
1782 e = SubElement(c, 'e')
1783
1784 self.assertEqual(
1785 [],
1786 list(a.iterdescendants('a')))
1787 a2 = SubElement(e, 'a')
1788 self.assertEqual(
1789 [a2],
1790 list(a.iterdescendants('a')))
1791 self.assertEqual(
1792 [a2],
1793 list(c.iterdescendants('a')))
1794
1796 Element = self.etree.Element
1797 SubElement = self.etree.SubElement
1798
1799 a = Element('a')
1800 b = SubElement(a, 'b')
1801 c = SubElement(a, 'c')
1802 d = SubElement(b, 'd')
1803 e = SubElement(c, 'e')
1804
1805 self.assertEqual(
1806 [b, e],
1807 list(a.iterdescendants(tag=('a', 'b', 'e'))))
1808 a2 = SubElement(e, 'a')
1809 self.assertEqual(
1810 [b, a2],
1811 list(a.iterdescendants(tag=('a', 'b'))))
1812 self.assertEqual(
1813 [],
1814 list(c.iterdescendants(tag=('x', 'y', 'z'))))
1815 self.assertEqual(
1816 [b, d, c, e, a2],
1817 list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
1818
1820 Element = self.etree.Element
1821 SubElement = self.etree.SubElement
1822
1823 a = Element('a')
1824 b = SubElement(a, 'b')
1825 c = SubElement(a, 'c')
1826 d = SubElement(b, 'd')
1827 self.assertEqual(
1828 a,
1829 a.getroottree().getroot())
1830 self.assertEqual(
1831 a,
1832 b.getroottree().getroot())
1833 self.assertEqual(
1834 a,
1835 d.getroottree().getroot())
1836
1838 Element = self.etree.Element
1839 SubElement = self.etree.SubElement
1840
1841 a = Element('a')
1842 b = SubElement(a, 'b')
1843 c = SubElement(a, 'c')
1844 self.assertEqual(
1845 None,
1846 a.getnext())
1847 self.assertEqual(
1848 c,
1849 b.getnext())
1850 self.assertEqual(
1851 None,
1852 c.getnext())
1853
1855 Element = self.etree.Element
1856 SubElement = self.etree.SubElement
1857
1858 a = Element('a')
1859 b = SubElement(a, 'b')
1860 c = SubElement(a, 'c')
1861 d = SubElement(b, 'd')
1862 self.assertEqual(
1863 None,
1864 a.getprevious())
1865 self.assertEqual(
1866 b,
1867 c.getprevious())
1868 self.assertEqual(
1869 None,
1870 b.getprevious())
1871
1873 Element = self.etree.Element
1874 SubElement = self.etree.SubElement
1875
1876 a = Element('a')
1877 b = SubElement(a, 'b')
1878 c = SubElement(a, 'c')
1879 d = SubElement(b, 'd')
1880 self.assertEqual(
1881 [],
1882 list(a.itersiblings()))
1883 self.assertEqual(
1884 [c],
1885 list(b.itersiblings()))
1886 self.assertEqual(
1887 [],
1888 list(c.itersiblings()))
1889 self.assertEqual(
1890 [b],
1891 list(c.itersiblings(preceding=True)))
1892 self.assertEqual(
1893 [],
1894 list(b.itersiblings(preceding=True)))
1895
1897 Element = self.etree.Element
1898 SubElement = self.etree.SubElement
1899
1900 a = Element('a')
1901 b = SubElement(a, 'b')
1902 c = SubElement(a, 'c')
1903 d = SubElement(b, 'd')
1904 self.assertEqual(
1905 [],
1906 list(a.itersiblings(tag='XXX')))
1907 self.assertEqual(
1908 [c],
1909 list(b.itersiblings(tag='c')))
1910 self.assertEqual(
1911 [c],
1912 list(b.itersiblings(tag='*')))
1913 self.assertEqual(
1914 [b],
1915 list(c.itersiblings(preceding=True, tag='b')))
1916 self.assertEqual(
1917 [],
1918 list(c.itersiblings(preceding=True, tag='c')))
1919
1921 Element = self.etree.Element
1922 SubElement = self.etree.SubElement
1923
1924 a = Element('a')
1925 b = SubElement(a, 'b')
1926 c = SubElement(a, 'c')
1927 d = SubElement(b, 'd')
1928 e = SubElement(a, 'e')
1929 self.assertEqual(
1930 [],
1931 list(a.itersiblings(tag=('XXX', 'YYY'))))
1932 self.assertEqual(
1933 [c, e],
1934 list(b.itersiblings(tag=('c', 'd', 'e'))))
1935 self.assertEqual(
1936 [b],
1937 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
1938 self.assertEqual(
1939 [c, b],
1940 list(e.itersiblings(preceding=True, tag=('c', '*'))))
1941
1943 parseid = self.etree.parseid
1944 XML = self.etree.XML
1945 xml_text = _bytes('''
1946 <!DOCTYPE document [
1947 <!ELEMENT document (h1,p)*>
1948 <!ELEMENT h1 (#PCDATA)>
1949 <!ATTLIST h1 myid ID #REQUIRED>
1950 <!ELEMENT p (#PCDATA)>
1951 <!ATTLIST p someid ID #REQUIRED>
1952 ]>
1953 <document>
1954 <h1 myid="chapter1">...</h1>
1955 <p id="note1" class="note">...</p>
1956 <p>Regular paragraph.</p>
1957 <p xml:id="xmlid">XML:ID paragraph.</p>
1958 <p someid="warn1" class="warning">...</p>
1959 </document>
1960 ''')
1961
1962 tree, dic = parseid(BytesIO(xml_text))
1963 root = tree.getroot()
1964 root2 = XML(xml_text)
1965 self.assertEqual(self._writeElement(root),
1966 self._writeElement(root2))
1967 expected = {
1968 "chapter1" : root[0],
1969 "xmlid" : root[3],
1970 "warn1" : root[4]
1971 }
1972 self.assertTrue("chapter1" in dic)
1973 self.assertTrue("warn1" in dic)
1974 self.assertTrue("xmlid" in dic)
1975 self._checkIDDict(dic, expected)
1976
1978 XMLDTDID = self.etree.XMLDTDID
1979 XML = self.etree.XML
1980 xml_text = _bytes('''
1981 <!DOCTYPE document [
1982 <!ELEMENT document (h1,p)*>
1983 <!ELEMENT h1 (#PCDATA)>
1984 <!ATTLIST h1 myid ID #REQUIRED>
1985 <!ELEMENT p (#PCDATA)>
1986 <!ATTLIST p someid ID #REQUIRED>
1987 ]>
1988 <document>
1989 <h1 myid="chapter1">...</h1>
1990 <p id="note1" class="note">...</p>
1991 <p>Regular paragraph.</p>
1992 <p xml:id="xmlid">XML:ID paragraph.</p>
1993 <p someid="warn1" class="warning">...</p>
1994 </document>
1995 ''')
1996
1997 root, dic = XMLDTDID(xml_text)
1998 root2 = XML(xml_text)
1999 self.assertEqual(self._writeElement(root),
2000 self._writeElement(root2))
2001 expected = {
2002 "chapter1" : root[0],
2003 "xmlid" : root[3],
2004 "warn1" : root[4]
2005 }
2006 self.assertTrue("chapter1" in dic)
2007 self.assertTrue("warn1" in dic)
2008 self.assertTrue("xmlid" in dic)
2009 self._checkIDDict(dic, expected)
2010
2012 XMLDTDID = self.etree.XMLDTDID
2013 XML = self.etree.XML
2014 xml_text = _bytes('''
2015 <document>
2016 <h1 myid="chapter1">...</h1>
2017 <p id="note1" class="note">...</p>
2018 <p>Regular paragraph.</p>
2019 <p someid="warn1" class="warning">...</p>
2020 </document>
2021 ''')
2022
2023 root, dic = XMLDTDID(xml_text)
2024 root2 = XML(xml_text)
2025 self.assertEqual(self._writeElement(root),
2026 self._writeElement(root2))
2027 expected = {}
2028 self._checkIDDict(dic, expected)
2029
2031 self.assertEqual(len(dic),
2032 len(expected))
2033 self.assertEqual(sorted(dic.items()),
2034 sorted(expected.items()))
2035 if sys.version_info < (3,):
2036 self.assertEqual(sorted(dic.iteritems()),
2037 sorted(expected.iteritems()))
2038 self.assertEqual(sorted(dic.keys()),
2039 sorted(expected.keys()))
2040 if sys.version_info < (3,):
2041 self.assertEqual(sorted(dic.iterkeys()),
2042 sorted(expected.iterkeys()))
2043 if sys.version_info < (3,):
2044 self.assertEqual(sorted(dic.values()),
2045 sorted(expected.values()))
2046 self.assertEqual(sorted(dic.itervalues()),
2047 sorted(expected.itervalues()))
2048
2050 etree = self.etree
2051
2052 r = {'foo': 'http://ns.infrae.com/foo'}
2053 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2054 self.assertEqual(
2055 'foo',
2056 e.prefix)
2057 self.assertEqual(
2058 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
2059 self._writeElement(e))
2060
2062 etree = self.etree
2063
2064 r = {None: 'http://ns.infrae.com/foo'}
2065 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2066 self.assertEqual(
2067 None,
2068 e.prefix)
2069 self.assertEqual(
2070 '{http://ns.infrae.com/foo}bar',
2071 e.tag)
2072 self.assertEqual(
2073 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
2074 self._writeElement(e))
2075
2077 etree = self.etree
2078
2079 r = {None: 'http://ns.infrae.com/foo',
2080 'hoi': 'http://ns.infrae.com/hoi'}
2081 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2082 e.set('{http://ns.infrae.com/hoi}test', 'value')
2083 self.assertEqual(
2084 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
2085 self._writeElement(e))
2086
2088 etree = self.etree
2089 r = {None: 'http://ns.infrae.com/foo',
2090 'hoi': 'http://ns.infrae.com/hoi'}
2091 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
2092 tree = etree.ElementTree(element=e)
2093 etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
2094 self.assertEqual(
2095 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
2096 self._writeElement(e))
2097
2099 etree = self.etree
2100
2101 r = {None: 'http://ns.infrae.com/foo'}
2102 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2103 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2104
2105 e1.append(e2)
2106
2107 self.assertEqual(
2108 None,
2109 e1.prefix)
2110 self.assertEqual(
2111 None,
2112 e1[0].prefix)
2113 self.assertEqual(
2114 '{http://ns.infrae.com/foo}bar',
2115 e1.tag)
2116 self.assertEqual(
2117 '{http://ns.infrae.com/foo}bar',
2118 e1[0].tag)
2119
2121 etree = self.etree
2122
2123 r = {None: 'http://ns.infrae.com/BAR'}
2124 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
2125 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2126
2127 e1.append(e2)
2128
2129 self.assertEqual(
2130 None,
2131 e1.prefix)
2132 self.assertNotEqual(
2133 None,
2134 e2.prefix)
2135 self.assertEqual(
2136 '{http://ns.infrae.com/BAR}bar',
2137 e1.tag)
2138 self.assertEqual(
2139 '{http://ns.infrae.com/foo}bar',
2140 e2.tag)
2141
2143 ns_href = "http://a.b.c"
2144 one = self.etree.fromstring(
2145 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
2146 baz = one[0][0]
2147
2148 two = self.etree.fromstring(
2149 _bytes('<root xmlns:ns="%s"/>' % ns_href))
2150 two.append(baz)
2151 del one # make sure the source document is deallocated
2152
2153 self.assertEqual('{%s}baz' % ns_href, baz.tag)
2154 self.assertEqual(
2155 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
2156 self.etree.tostring(two))
2157
2159 xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>')
2160 root = self.etree.fromstring(xml)
2161 self.assertEqual(xml,
2162 self.etree.tostring(root))
2163 self.etree.cleanup_namespaces(root)
2164 self.assertEqual(
2165 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'),
2166 self.etree.tostring(root))
2167
2169 etree = self.etree
2170
2171 r = {None: 'http://ns.infrae.com/foo',
2172 'hoi': 'http://ns.infrae.com/hoi'}
2173 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
2174 self.assertEqual(
2175 r,
2176 e.nsmap)
2177
2179 etree = self.etree
2180
2181 re = {None: 'http://ns.infrae.com/foo',
2182 'hoi': 'http://ns.infrae.com/hoi'}
2183 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
2184
2185 rs = {None: 'http://ns.infrae.com/honk',
2186 'top': 'http://ns.infrae.com/top'}
2187 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
2188
2189 r = re.copy()
2190 r.update(rs)
2191 self.assertEqual(re, e.nsmap)
2192 self.assertEqual(r, s.nsmap)
2193
2195 etree = self.etree
2196 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
2197 self.assertEqual({'hha': None}, el.nsmap)
2198
2200 Element = self.etree.Element
2201 SubElement = self.etree.SubElement
2202
2203 a = Element('a')
2204 b = SubElement(a, 'b')
2205 c = SubElement(a, 'c')
2206 d = SubElement(b, 'd')
2207 e = SubElement(c, 'e')
2208 f = SubElement(c, 'f')
2209
2210 self.assertEqual(
2211 [a, b],
2212 list(a.getiterator('a', 'b')))
2213 self.assertEqual(
2214 [],
2215 list(a.getiterator('x', 'y')))
2216 self.assertEqual(
2217 [a, f],
2218 list(a.getiterator('f', 'a')))
2219 self.assertEqual(
2220 [c, e, f],
2221 list(c.getiterator('c', '*', 'a')))
2222 self.assertEqual(
2223 [],
2224 list(a.getiterator( (), () )))
2225
2227 Element = self.etree.Element
2228 SubElement = self.etree.SubElement
2229
2230 a = Element('a')
2231 b = SubElement(a, 'b')
2232 c = SubElement(a, 'c')
2233 d = SubElement(b, 'd')
2234 e = SubElement(c, 'e')
2235 f = SubElement(c, 'f')
2236
2237 self.assertEqual(
2238 [a, b],
2239 list(a.getiterator( ('a', 'b') )))
2240 self.assertEqual(
2241 [],
2242 list(a.getiterator( ('x', 'y') )))
2243 self.assertEqual(
2244 [a, f],
2245 list(a.getiterator( ('f', 'a') )))
2246 self.assertEqual(
2247 [c, e, f],
2248 list(c.getiterator( ('c', '*', 'a') )))
2249 self.assertEqual(
2250 [],
2251 list(a.getiterator( () )))
2252
2254 Element = self.etree.Element
2255 SubElement = self.etree.SubElement
2256
2257 a = Element('{a}a')
2258 b = SubElement(a, '{a}b')
2259 c = SubElement(a, '{a}c')
2260 d = SubElement(b, '{b}d')
2261 e = SubElement(c, '{a}e')
2262 f = SubElement(c, '{b}f')
2263 g = SubElement(c, 'g')
2264
2265 self.assertEqual(
2266 [a],
2267 list(a.getiterator('{a}a')))
2268 self.assertEqual(
2269 [],
2270 list(a.getiterator('{b}a')))
2271 self.assertEqual(
2272 [],
2273 list(a.getiterator('a')))
2274 self.assertEqual(
2275 [a,b,d,c,e,f,g],
2276 list(a.getiterator('*')))
2277 self.assertEqual(
2278 [f],
2279 list(c.getiterator('{b}*')))
2280 self.assertEqual(
2281 [d, f],
2282 list(a.getiterator('{b}*')))
2283 self.assertEqual(
2284 [g],
2285 list(a.getiterator('g')))
2286 self.assertEqual(
2287 [g],
2288 list(a.getiterator('{}g')))
2289 self.assertEqual(
2290 [g],
2291 list(a.getiterator('{}*')))
2292
2294 Element = self.etree.Element
2295 SubElement = self.etree.SubElement
2296
2297 a = Element('{a}a')
2298 b = SubElement(a, '{nsA}b')
2299 c = SubElement(b, '{nsB}b')
2300 d = SubElement(a, 'b')
2301 e = SubElement(a, '{nsA}e')
2302 f = SubElement(e, '{nsB}e')
2303 g = SubElement(e, 'e')
2304
2305 self.assertEqual(
2306 [b, c, d],
2307 list(a.getiterator('{*}b')))
2308 self.assertEqual(
2309 [e, f, g],
2310 list(a.getiterator('{*}e')))
2311 self.assertEqual(
2312 [a, b, c, d, e, f, g],
2313 list(a.getiterator('{*}*')))
2314
2316 Element = self.etree.Element
2317 Entity = self.etree.Entity
2318 SubElement = self.etree.SubElement
2319
2320 a = Element('a')
2321 b = SubElement(a, 'b')
2322 entity_b = Entity("TEST-b")
2323 b.append(entity_b)
2324
2325 self.assertEqual(
2326 [entity_b],
2327 list(a.getiterator(Entity)))
2328
2329 entity_a = Entity("TEST-a")
2330 a.append(entity_a)
2331
2332 self.assertEqual(
2333 [entity_b, entity_a],
2334 list(a.getiterator(Entity)))
2335
2336 self.assertEqual(
2337 [entity_b],
2338 list(b.getiterator(Entity)))
2339
2341 Element = self.etree.Element
2342 Comment = self.etree.Comment
2343 PI = self.etree.PI
2344 SubElement = self.etree.SubElement
2345
2346 a = Element('a')
2347 b = SubElement(a, 'b')
2348 a.append(Comment("test"))
2349 a.append(PI("pi", "content"))
2350 c = SubElement(a, 'c')
2351
2352 self.assertEqual(
2353 [a, b, c],
2354 list(a.getiterator(Element)))
2355
2357 # ElementTree iterates over everything here
2358 Element = self.etree.Element
2359 Comment = self.etree.Comment
2360 PI = self.etree.PI
2361 SubElement = self.etree.SubElement
2362
2363 a = Element('a')
2364 b = SubElement(a, 'b')
2365 a.append(Comment("test"))
2366 a.append(PI("pi", "content"))
2367 c = SubElement(a, 'c')
2368
2369 self.assertEqual(
2370 [a, b, c],
2371 list(a.getiterator('*')))
2372
2374 XML = self.etree.XML
2375 ElementTree = self.etree.ElementTree
2376 QName = self.etree.QName
2377 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
2378 self.assertEqual(tree.find(QName("c")), tree.getroot()[2])
2379
2381 XML = self.etree.XML
2382 ElementTree = self.etree.ElementTree
2383 QName = self.etree.QName
2384 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
2385 self.assertEqual(len(list(tree.findall(QName("c")))), 1)
2386
2388 XML = self.etree.XML
2389 ElementTree = self.etree.ElementTree
2390 QName = self.etree.QName
2391 tree = ElementTree(XML(
2392 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')))
2393 self.assertEqual(len(list(tree.findall(QName("b")))), 2)
2394 self.assertEqual(len(list(tree.findall(QName("X", "b")))), 1)
2395
2397 XML = self.etree.XML
2398 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
2399 self.assertEqual(len(root.findall(".//{X}b")), 2)
2400 self.assertEqual(len(root.findall(".//{X}*")), 2)
2401 self.assertEqual(len(root.findall(".//b")), 3)
2402
2404 XML = self.etree.XML
2405 root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>'))
2406 self.assertRaises(SyntaxError, root.findall, '')
2407 self.assertRaises(SyntaxError, root.findall, '//') # absolute path on Element
2408 self.assertRaises(SyntaxError, root.findall, './//')
2409
2411 etree = self.etree
2412 e = etree.Element('foo')
2413 for i in range(10):
2414 etree.SubElement(e, 'a%s' % i)
2415 for i in range(10):
2416 self.assertEqual(
2417 i,
2418 e.index(e[i]))
2419 self.assertEqual(
2420 3, e.index(e[3], 3))
2421 self.assertRaises(
2422 ValueError, e.index, e[3], 4)
2423 self.assertRaises(
2424 ValueError, e.index, e[3], 0, 2)
2425 self.assertRaises(
2426 ValueError, e.index, e[8], 0, -3)
2427 self.assertRaises(
2428 ValueError, e.index, e[8], -5, -3)
2429 self.assertEqual(
2430 8, e.index(e[8], 0, -1))
2431 self.assertEqual(
2432 8, e.index(e[8], -12, -1))
2433 self.assertEqual(
2434 0, e.index(e[0], -12, -1))
2435
2437 etree = self.etree
2438 e = etree.Element('foo')
2439 for i in range(10):
2440 el = etree.SubElement(e, 'a%s' % i)
2441 el.text = "text%d" % i
2442 el.tail = "tail%d" % i
2443
2444 child0 = e[0]
2445 child1 = e[1]
2446 child2 = e[2]
2447
2448 e.replace(e[0], e[1])
2449 self.assertEqual(
2450 9, len(e))
2451 self.assertEqual(
2452 child1, e[0])
2453 self.assertEqual(
2454 child1.text, "text1")
2455 self.assertEqual(
2456 child1.tail, "tail1")
2457 self.assertEqual(
2458 child0.tail, "tail0")
2459 self.assertEqual(
2460 child2, e[1])
2461
2462 e.replace(e[-1], e[0])
2463 self.assertEqual(
2464 child1, e[-1])
2465 self.assertEqual(
2466 child1.text, "text1")
2467 self.assertEqual(
2468 child1.tail, "tail1")
2469 self.assertEqual(
2470 child2, e[0])
2471
2473 etree = self.etree
2474 e = etree.Element('foo')
2475 for i in range(10):
2476 etree.SubElement(e, 'a%s' % i)
2477
2478 new_element = etree.Element("test")
2479 new_element.text = "TESTTEXT"
2480 new_element.tail = "TESTTAIL"
2481 child1 = e[1]
2482 e.replace(e[0], new_element)
2483 self.assertEqual(
2484 new_element, e[0])
2485 self.assertEqual(
2486 "TESTTEXT",
2487 e[0].text)
2488 self.assertEqual(
2489 "TESTTAIL",
2490 e[0].tail)
2491 self.assertEqual(
2492 child1, e[1])
2493
2495 Element = self.etree.Element
2496 SubElement = self.etree.SubElement
2497
2498 a = Element('a')
2499
2500 e = Element('e')
2501 f = Element('f')
2502 g = Element('g')
2503
2504 s = [e, f, g]
2505 a[::-1] = s
2506 self.assertEqual(
2507 [g, f, e],
2508 list(a))
2509
2511 Element = self.etree.Element
2512 SubElement = self.etree.SubElement
2513
2514 a = Element('a')
2515 b = SubElement(a, 'b')
2516 c = SubElement(a, 'c')
2517 d = SubElement(a, 'd')
2518 e = SubElement(a, 'e')
2519
2520 x = Element('x')
2521 y = Element('y')
2522
2523 a[1::2] = [x, y]
2524 self.assertEqual(
2525 [b, x, d, y],
2526 list(a))
2527
2529 Element = self.etree.Element
2530 SubElement = self.etree.SubElement
2531
2532 a = Element('a')
2533 b = SubElement(a, 'b')
2534 c = SubElement(a, 'c')
2535 d = SubElement(a, 'd')
2536 e = SubElement(a, 'e')
2537
2538 x = Element('x')
2539 y = Element('y')
2540
2541 a[1::-1] = [x, y]
2542 self.assertEqual(
2543 [y, x, d, e],
2544 list(a))
2545
2547 Element = self.etree.Element
2548 SubElement = self.etree.SubElement
2549
2550 a = Element('a')
2551 b = SubElement(a, 'b')
2552 c = SubElement(a, 'c')
2553 d = SubElement(a, 'd')
2554 e = SubElement(a, 'e')
2555
2556 x = Element('x')
2557 y = Element('y')
2558
2559 a[::-2] = [x, y]
2560 self.assertEqual(
2561 [b, y, d, x],
2562 list(a))
2563
2565 Element = self.etree.Element
2566 SubElement = self.etree.SubElement
2567 try:
2568 slice
2569 except NameError:
2570 print("slice() not found")
2571 return
2572
2573 a = Element('a')
2574 b = SubElement(a, 'b')
2575 c = SubElement(a, 'c')
2576 d = SubElement(a, 'd')
2577 e = SubElement(a, 'e')
2578
2579 x = Element('x')
2580 y = Element('y')
2581 z = Element('z')
2582
2583 self.assertRaises(
2584 ValueError,
2585 operator.setitem, a, slice(1,None,2), [x, y, z])
2586
2587 self.assertEqual(
2588 [b, c, d, e],
2589 list(a))
2590
2592 XML = self.etree.XML
2593 root = XML(_bytes('''<?xml version="1.0"?>
2594 <root><test>
2595
2596 <bla/></test>
2597 </root>
2598 '''))
2599
2600 self.assertEqual(
2601 [2, 2, 4],
2602 [ el.sourceline for el in root.getiterator() ])
2603
2605 parse = self.etree.parse
2606 tree = parse(fileInTestDir('include/test_xinclude.xml'))
2607
2608 self.assertEqual(
2609 [1, 2, 3],
2610 [ el.sourceline for el in tree.getiterator() ])
2611
2613 iterparse = self.etree.iterparse
2614 lines = [ el.sourceline for (event, el) in
2615 iterparse(fileInTestDir('include/test_xinclude.xml')) ]
2616
2617 self.assertEqual(
2618 [2, 3, 1],
2619 lines)
2620
2622 iterparse = self.etree.iterparse
2623 lines = [ el.sourceline for (event, el) in
2624 iterparse(fileInTestDir('include/test_xinclude.xml'),
2625 events=("start",)) ]
2626
2627 self.assertEqual(
2628 [1, 2, 3],
2629 lines)
2630
2632 Element = self.etree.Element
2633 SubElement = self.etree.SubElement
2634 el = Element("test")
2635 self.assertEqual(None, el.sourceline)
2636
2637 child = SubElement(el, "test")
2638 self.assertEqual(None, el.sourceline)
2639 self.assertEqual(None, child.sourceline)
2640
2642 etree = self.etree
2643 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2644 docinfo = root.getroottree().docinfo
2645 self.assertEqual(docinfo.URL, "http://no/such/url")
2646
2648 etree = self.etree
2649 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2650 docinfo = root.getroottree().docinfo
2651 self.assertEqual(docinfo.URL, "http://no/such/url")
2652 docinfo.URL = "https://secret/url"
2653 self.assertEqual(docinfo.URL, "https://secret/url")
2654
2656 etree = self.etree
2657 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url")
2658 docinfo = tree.docinfo
2659 self.assertEqual(docinfo.URL, "http://no/such/url")
2660
2662 etree = self.etree
2663 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
2664 base_url="http://no/such/url")
2665 docinfo = tree.docinfo
2666 self.assertEqual(docinfo.URL, "http://no/such/url")
2667
2669 etree = self.etree
2670 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url")
2671 docinfo = root.getroottree().docinfo
2672 self.assertEqual(docinfo.URL, "http://no/such/url")
2673
2675 etree = self.etree
2676 xml_header = '<?xml version="1.0" encoding="ascii"?>'
2677 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2678 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2679 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
2680
2681 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
2682
2683 tree = etree.parse(BytesIO(xml))
2684 docinfo = tree.docinfo
2685 self.assertEqual(docinfo.encoding, "ascii")
2686 self.assertEqual(docinfo.xml_version, "1.0")
2687 self.assertEqual(docinfo.public_id, pub_id)
2688 self.assertEqual(docinfo.system_url, sys_id)
2689 self.assertEqual(docinfo.root_name, 'html')
2690 self.assertEqual(docinfo.doctype, doctype_string)
2691
2693 etree = self.etree
2694 xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
2695 sys_id = "some.dtd"
2696 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
2697 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
2698
2699 tree = etree.parse(BytesIO(xml))
2700 docinfo = tree.docinfo
2701 self.assertEqual(docinfo.encoding, "UTF-8")
2702 self.assertEqual(docinfo.xml_version, "1.0")
2703 self.assertEqual(docinfo.public_id, None)
2704 self.assertEqual(docinfo.system_url, sys_id)
2705 self.assertEqual(docinfo.root_name, 'html')
2706 self.assertEqual(docinfo.doctype, doctype_string)
2707
2709 etree = self.etree
2710 xml = _bytes('<html><body></body></html>')
2711 tree = etree.parse(BytesIO(xml))
2712 docinfo = tree.docinfo
2713 self.assertEqual(docinfo.encoding, "UTF-8")
2714 self.assertEqual(docinfo.xml_version, "1.0")
2715 self.assertEqual(docinfo.public_id, None)
2716 self.assertEqual(docinfo.system_url, None)
2717 self.assertEqual(docinfo.root_name, 'html')
2718 self.assertEqual(docinfo.doctype, '')
2719
2721 etree = self.etree
2722 xml = _bytes('<!DOCTYPE root><root></root>')
2723 tree = etree.parse(BytesIO(xml))
2724 docinfo = tree.docinfo
2725 self.assertEqual(docinfo.encoding, "UTF-8")
2726 self.assertEqual(docinfo.xml_version, "1.0")
2727 self.assertEqual(docinfo.public_id, None)
2728 self.assertEqual(docinfo.system_url, None)
2729 self.assertEqual(docinfo.root_name, 'root')
2730 self.assertEqual(docinfo.doctype, '<!DOCTYPE root>')
2731
2733 etree = self.etree
2734 xml = _bytes('<!DOCTYPE root>\n<root/>')
2735 tree = etree.parse(BytesIO(xml))
2736 self.assertEqual(xml, etree.tostring(tree))
2737
2739 etree = self.etree
2740 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
2741 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
2742 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
2743
2744 xml = _bytes('<!DOCTYPE root>\n<root/>')
2745 tree = etree.parse(BytesIO(xml))
2746 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
2747 etree.tostring(tree, doctype=doctype_string))
2748
2750 etree = self.etree
2751 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2752 self.assertEqual(root.base, "http://no/such/url")
2753 self.assertEqual(
2754 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2755 root.base = "https://secret/url"
2756 self.assertEqual(root.base, "https://secret/url")
2757 self.assertEqual(
2758 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2759 "https://secret/url")
2760
2762 etree = self.etree
2763 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
2764 self.assertEqual(root.base, "http://no/such/url")
2765 self.assertEqual(
2766 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2767 root.set('{http://www.w3.org/XML/1998/namespace}base',
2768 "https://secret/url")
2769 self.assertEqual(root.base, "https://secret/url")
2770 self.assertEqual(
2771 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2772 "https://secret/url")
2773
2775 etree = self.etree
2776 root = etree.HTML(_bytes("<html><body></body></html>"),
2777 base_url="http://no/such/url")
2778 self.assertEqual(root.base, "http://no/such/url")
2779
2781 etree = self.etree
2782 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>'))
2783 self.assertEqual(root.base, "http://no/such/url")
2784
2786 # parse from a file object that returns unicode strings
2787 f = LargeFileLikeUnicode()
2788 tree = self.etree.parse(f)
2789 root = tree.getroot()
2790 self.assertTrue(root.tag.endswith('root'))
2791
2793 # check that DTDs that go in also go back out
2794 xml = _bytes('''\
2795 <!DOCTYPE test SYSTEM "test.dtd" [
2796 <!ENTITY entity "tasty">
2797 <!ELEMENT test (a)>
2798 <!ELEMENT a (#PCDATA)>
2799 ]>
2800 <test><a>test-test</a></test>\
2801 ''')
2802 tree = self.etree.parse(BytesIO(xml))
2803 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")),
2804 xml.replace(_bytes(" "), _bytes("")))
2805
2807 Element = self.etree.Element
2808
2809 a = Element('a')
2810 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
2811 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
2812
2813 self.assertRaises(ValueError, Element, 'ha\0ho')
2814
2816 Element = self.etree.Element
2817
2818 a = Element('a')
2819 self.assertRaises(ValueError, setattr, a, "text",
2820 _str('ha\0ho'))
2821 self.assertRaises(ValueError, setattr, a, "tail",
2822 _str('ha\0ho'))
2823
2824 self.assertRaises(ValueError, Element,
2825 _str('ha\0ho'))
2826
2828 Element = self.etree.Element
2829
2830 a = Element('a')
2831 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
2832 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
2833
2834 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
2835 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
2836
2837 self.assertRaises(ValueError, Element, 'ha\x07ho')
2838 self.assertRaises(ValueError, Element, 'ha\x02ho')
2839
2841 Element = self.etree.Element
2842
2843 a = Element('a')
2844 self.assertRaises(ValueError, setattr, a, "text",
2845 _str('ha\x07ho'))
2846 self.assertRaises(ValueError, setattr, a, "text",
2847 _str('ha\x02ho'))
2848
2849 self.assertRaises(ValueError, setattr, a, "tail",
2850 _str('ha\x07ho'))
2851 self.assertRaises(ValueError, setattr, a, "tail",
2852 _str('ha\x02ho'))
2853
2854 self.assertRaises(ValueError, Element,
2855 _str('ha\x07ho'))
2856 self.assertRaises(ValueError, Element,
2857 _str('ha\x02ho'))
2858
2860 Element = self.etree.Element
2861
2862 a = Element('a')
2863 self.assertRaises(ValueError, setattr, a, "text",
2864 _str('ha\u1234\x07ho'))
2865 self.assertRaises(ValueError, setattr, a, "text",
2866 _str('ha\u1234\x02ho'))
2867
2868 self.assertRaises(ValueError, setattr, a, "tail",
2869 _str('ha\u1234\x07ho'))
2870 self.assertRaises(ValueError, setattr, a, "tail",
2871 _str('ha\u1234\x02ho'))
2872
2873 self.assertRaises(ValueError, Element,
2874 _str('ha\u1234\x07ho'))
2875 self.assertRaises(ValueError, Element,
2876 _str('ha\u1234\x02ho'))
2877
2879 # ElementTree fails to serialize this
2880 tostring = self.etree.tostring
2881 Element = self.etree.Element
2882 SubElement = self.etree.SubElement
2883
2884 a = Element('a')
2885 b = SubElement(a, 'b')
2886 c = SubElement(a, 'c')
2887
2888 result = tostring(a, encoding='UTF-16')
2889 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
2890 canonicalize(result))
2891
2893 # ElementTree raises an AssertionError here
2894 tostring = self.etree.tostring
2895 self.assertRaises(TypeError, self.etree.tostring, None)
2896
2898 tostring = self.etree.tostring
2899 Element = self.etree.Element
2900 SubElement = self.etree.SubElement
2901
2902 a = Element('a')
2903 b = SubElement(a, 'b')
2904 c = SubElement(a, 'c')
2905
2906 result = tostring(a)
2907 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
2908
2909 result = tostring(a, pretty_print=False)
2910 self.assertEqual(result, _bytes("<a><b/><c/></a>"))
2911
2912 result = tostring(a, pretty_print=True)
2913 self.assertEqual(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
2914
2916 tostring = self.etree.tostring
2917 Element = self.etree.Element
2918 SubElement = self.etree.SubElement
2919
2920 a = Element('a')
2921 a.tail = "aTAIL"
2922 b = SubElement(a, 'b')
2923 b.tail = "bTAIL"
2924 c = SubElement(a, 'c')
2925
2926 result = tostring(a)
2927 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
2928
2929 result = tostring(a, with_tail=False)
2930 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>"))
2931
2932 result = tostring(a, with_tail=True)
2933 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
2934
2936 tostring = self.etree.tostring
2937 XML = self.etree.XML
2938 ElementTree = self.etree.ElementTree
2939 Element = self.etree.Element
2940
2941 tree = Element("root").getroottree()
2942 self.assertEqual(None, tree.docinfo.standalone)
2943
2944 tree = XML(_bytes("<root/>")).getroottree()
2945 self.assertEqual(None, tree.docinfo.standalone)
2946
2947 tree = XML(_bytes(
2948 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"
2949 )).getroottree()
2950 self.assertEqual(True, tree.docinfo.standalone)
2951
2952 tree = XML(_bytes(
2953 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"
2954 )).getroottree()
2955 self.assertEqual(False, tree.docinfo.standalone)
2956
2958 tostring = self.etree.tostring
2959 XML = self.etree.XML
2960 ElementTree = self.etree.ElementTree
2961
2962 root = XML(_bytes("<root/>"))
2963
2964 tree = ElementTree(root)
2965 self.assertEqual(None, tree.docinfo.standalone)
2966
2967 result = tostring(root, xml_declaration=True, encoding="ASCII")
2968 self.assertEqual(result, _bytes(
2969 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
2970
2971 result = tostring(root, xml_declaration=True, encoding="ASCII",
2972 standalone=True)
2973 self.assertEqual(result, _bytes(
2974 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
2975
2976 tree = ElementTree(XML(result))
2977 self.assertEqual(True, tree.docinfo.standalone)
2978
2979 result = tostring(root, xml_declaration=True, encoding="ASCII",
2980 standalone=False)
2981 self.assertEqual(result, _bytes(
2982 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
2983
2984 tree = ElementTree(XML(result))
2985 self.assertEqual(False, tree.docinfo.standalone)
2986
2988 tostring = self.etree.tostring
2989 XML = self.etree.XML
2990 ElementTree = self.etree.ElementTree
2991
2992 root = XML(_bytes(
2993 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>"))
2994
2995 tree = ElementTree(root)
2996 self.assertEqual(True, tree.docinfo.standalone)
2997
2998 result = tostring(root, xml_declaration=True, encoding="ASCII")
2999 self.assertEqual(result, _bytes(
3000 "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
3001
3002 result = tostring(root, xml_declaration=True, encoding="ASCII",
3003 standalone=True)
3004 self.assertEqual(result, _bytes(
3005 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3006
3008 tostring = self.etree.tostring
3009 Element = self.etree.Element
3010 SubElement = self.etree.SubElement
3011
3012 a = Element('a')
3013 a.text = "A"
3014 a.tail = "tail"
3015 b = SubElement(a, 'b')
3016 b.text = "B"
3017 b.tail = _str("Søk på nettet")
3018 c = SubElement(a, 'c')
3019 c.text = "C"
3020
3021 result = tostring(a, method="text", encoding="UTF-16")
3022
3023 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"),
3024 result)
3025
3027 tostring = self.etree.tostring
3028 Element = self.etree.Element
3029 SubElement = self.etree.SubElement
3030
3031 a = Element('a')
3032 a.text = _str('Søk på nettetA')
3033 a.tail = "tail"
3034 b = SubElement(a, 'b')
3035 b.text = "B"
3036 b.tail = _str('Søk på nettetB')
3037 c = SubElement(a, 'c')
3038 c.text = "C"
3039
3040 self.assertRaises(UnicodeEncodeError,
3041 tostring, a, method="text")
3042
3043 self.assertEqual(
3044 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
3045 tostring(a, encoding="UTF-8", method="text"))
3046
3048 tounicode = self.etree.tounicode
3049 Element = self.etree.Element
3050 SubElement = self.etree.SubElement
3051
3052 a = Element('a')
3053 b = SubElement(a, 'b')
3054 c = SubElement(a, 'c')
3055
3056 self.assertTrue(isinstance(tounicode(a), _unicode))
3057 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3058 canonicalize(tounicode(a)))
3059
3061 tounicode = self.etree.tounicode
3062 Element = self.etree.Element
3063 SubElement = self.etree.SubElement
3064
3065 a = Element('a')
3066 b = SubElement(a, 'b')
3067 c = SubElement(a, 'c')
3068 d = SubElement(c, 'd')
3069 self.assertTrue(isinstance(tounicode(b), _unicode))
3070 self.assertTrue(isinstance(tounicode(c), _unicode))
3071 self.assertEqual(_bytes('<b></b>'),
3072 canonicalize(tounicode(b)))
3073 self.assertEqual(_bytes('<c><d></d></c>'),
3074 canonicalize(tounicode(c)))
3075
3079
3081 tounicode = self.etree.tounicode
3082 Element = self.etree.Element
3083 SubElement = self.etree.SubElement
3084
3085 a = Element('a')
3086 b = SubElement(a, 'b')
3087 c = SubElement(a, 'c')
3088 d = SubElement(c, 'd')
3089 b.tail = 'Foo'
3090
3091 self.assertTrue(isinstance(tounicode(b), _unicode))
3092 self.assertTrue(tounicode(b) == '<b/>Foo' or
3093 tounicode(b) == '<b />Foo')
3094
3096 tounicode = self.etree.tounicode
3097 Element = self.etree.Element
3098 SubElement = self.etree.SubElement
3099
3100 a = Element('a')
3101 b = SubElement(a, 'b')
3102 c = SubElement(a, 'c')
3103
3104 result = tounicode(a)
3105 self.assertEqual(result, "<a><b/><c/></a>")
3106
3107 result = tounicode(a, pretty_print=False)
3108 self.assertEqual(result, "<a><b/><c/></a>")
3109
3110 result = tounicode(a, pretty_print=True)
3111 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3112
3114 tostring = self.etree.tostring
3115 Element = self.etree.Element
3116 SubElement = self.etree.SubElement
3117
3118 a = Element('a')
3119 b = SubElement(a, 'b')
3120 c = SubElement(a, 'c')
3121
3122 self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode))
3123 self.assertEqual(_bytes('<a><b></b><c></c></a>'),
3124 canonicalize(tostring(a, encoding=_unicode)))
3125
3127 tostring = self.etree.tostring
3128 Element = self.etree.Element
3129 SubElement = self.etree.SubElement
3130
3131 a = Element('a')
3132 b = SubElement(a, 'b')
3133 c = SubElement(a, 'c')
3134 d = SubElement(c, 'd')
3135 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3136 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode))
3137 self.assertEqual(_bytes('<b></b>'),
3138 canonicalize(tostring(b, encoding=_unicode)))
3139 self.assertEqual(_bytes('<c><d></d></c>'),
3140 canonicalize(tostring(c, encoding=_unicode)))
3141
3143 tostring = self.etree.tostring
3144 self.assertRaises(TypeError, self.etree.tostring,
3145 None, encoding=_unicode)
3146
3148 tostring = self.etree.tostring
3149 Element = self.etree.Element
3150 SubElement = self.etree.SubElement
3151
3152 a = Element('a')
3153 b = SubElement(a, 'b')
3154 c = SubElement(a, 'c')
3155 d = SubElement(c, 'd')
3156 b.tail = 'Foo'
3157
3158 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode))
3159 self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or
3160 tostring(b, encoding=_unicode) == '<b />Foo')
3161
3163 tostring = self.etree.tostring
3164 Element = self.etree.Element
3165 SubElement = self.etree.SubElement
3166
3167 a = Element('a')
3168 b = SubElement(a, 'b')
3169 c = SubElement(a, 'c')
3170
3171 result = tostring(a, encoding=_unicode)
3172 self.assertEqual(result, "<a><b/><c/></a>")
3173
3174 result = tostring(a, encoding=_unicode, pretty_print=False)
3175 self.assertEqual(result, "<a><b/><c/></a>")
3176
3177 result = tostring(a, encoding=_unicode, pretty_print=True)
3178 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3179
3181 root = etree.Element('parent')
3182 etree.SubElement(root, 'child')
3183
3184 self.assertEqual(len(root), 1)
3185 self.assertEqual(root[0].tag, 'child')
3186
3187 # in PyPy, GC used to kill the Python proxy instance without cleanup
3188 gc.collect()
3189 self.assertEqual(len(root), 1)
3190 self.assertEqual(root[0].tag, 'child')
3191
3192 # helper methods
3193
3195 """Write out element for comparison.
3196 """
3197 ElementTree = self.etree.ElementTree
3198 f = BytesIO()
3199 tree = ElementTree(element=element)
3200 tree.write(f, encoding=encoding, compression=compression)
3201 data = f.getvalue()
3202 if compression:
3203 data = zlib.decompress(data)
3204 return canonicalize(data)
3205
3206
3209 filename = fileInTestDir('test_broken.xml')
3210 root = etree.XML(_bytes('''\
3211 <doc xmlns:xi="http://www.w3.org/2001/XInclude">
3212 <xi:include href="%s" parse="text"/>
3213 </doc>
3214 ''' % filename))
3215 old_text = root.text
3216 content = read_file(filename)
3217 old_tail = root[0].tail
3218
3219 self.include( etree.ElementTree(root) )
3220 self.assertEqual(old_text + content + old_tail,
3221 root.text)
3222
3224 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
3225 self.assertNotEqual(
3226 'a',
3227 tree.getroot()[1].tag)
3228 # process xincludes
3229 self.include( tree )
3230 # check whether we find it replaced with included data
3231 self.assertEqual(
3232 'a',
3233 tree.getroot()[1].tag)
3234
3236 class res(etree.Resolver):
3237 include_text = read_file(fileInTestDir('test.xml'))
3238 called = {}
3239 def resolve(self, url, id, context):
3240 if url.endswith(".dtd"):
3241 self.called["dtd"] = True
3242 return self.resolve_filename(
3243 fileInTestDir('test.dtd'), context)
3244 elif url.endswith("test_xinclude.xml"):
3245 self.called["input"] = True
3246 return None # delegate to default resolver
3247 else:
3248 self.called["include"] = True
3249 return self.resolve_string(self.include_text, context)
3250
3251 res_instance = res()
3252 parser = etree.XMLParser(load_dtd = True)
3253 parser.resolvers.add(res_instance)
3254
3255 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
3256 parser = parser)
3257
3258 self.include(tree)
3259
3260 called = list(res_instance.called.items())
3261 called.sort()
3262 self.assertEqual(
3263 [("dtd", True), ("include", True), ("input", True)],
3264 called)
3265
3269
3270
3275
3276
3279 tree = self.parse(_bytes('<a><b/></a>'))
3280 f = BytesIO()
3281 tree.write_c14n(f)
3282 s = f.getvalue()
3283 self.assertEqual(_bytes('<a><b></b></a>'),
3284 s)
3285
3287 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3288 f = BytesIO()
3289 tree.write_c14n(f, compression=9)
3290 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3291 try:
3292 s = gzfile.read()
3293 finally:
3294 gzfile.close()
3295 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3296 s)
3297
3299 tree = self.parse(_bytes('<a><b/></a>'))
3300 handle, filename = tempfile.mkstemp()
3301 try:
3302 tree.write_c14n(filename)
3303 data = read_file(filename, 'rb')
3304 finally:
3305 os.close(handle)
3306 os.remove(filename)
3307 self.assertEqual(_bytes('<a><b></b></a>'),
3308 data)
3309
3311 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3312 handle, filename = tempfile.mkstemp()
3313 try:
3314 tree.write_c14n(filename, compression=9)
3315 f = gzip.open(filename, 'rb')
3316 try:
3317 data = f.read()
3318 finally:
3319 f.close()
3320 finally:
3321 os.close(handle)
3322 os.remove(filename)
3323 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'),
3324 data)
3325
3327 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3328 f = BytesIO()
3329 tree.write_c14n(f)
3330 s = f.getvalue()
3331 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3332 s)
3333 f = BytesIO()
3334 tree.write_c14n(f, with_comments=True)
3335 s = f.getvalue()
3336 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3337 s)
3338 f = BytesIO()
3339 tree.write_c14n(f, with_comments=False)
3340 s = f.getvalue()
3341 self.assertEqual(_bytes('<a><b></b></a>'),
3342 s)
3343
3345 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3346 s = etree.tostring(tree, method='c14n')
3347 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3348 s)
3349 s = etree.tostring(tree, method='c14n', with_comments=True)
3350 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
3351 s)
3352 s = etree.tostring(tree, method='c14n', with_comments=False)
3353 self.assertEqual(_bytes('<a><b></b></a>'),
3354 s)
3355
3357 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
3358 s = etree.tostring(tree.getroot(), method='c14n')
3359 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
3360 s)
3361 s = etree.tostring(tree.getroot(), method='c14n', with_comments=True)
3362 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'),
3363 s)
3364 s = etree.tostring(tree.getroot(), method='c14n', with_comments=False)
3365 self.assertEqual(_bytes('<a><b></b></a>'),
3366 s)
3367
3369 tree = self.parse(_bytes(
3370 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3371 f = BytesIO()
3372 tree.write_c14n(f)
3373 s = f.getvalue()
3374 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3375 s)
3376 f = BytesIO()
3377 tree.write_c14n(f, exclusive=False)
3378 s = f.getvalue()
3379 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3380 s)
3381 f = BytesIO()
3382 tree.write_c14n(f, exclusive=True)
3383 s = f.getvalue()
3384 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3385 s)
3386
3387 f = BytesIO()
3388 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
3389 s = f.getvalue()
3390 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
3391 s)
3392
3394 tree = self.parse(_bytes(
3395 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3396 s = etree.tostring(tree, method='c14n')
3397 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3398 s)
3399 s = etree.tostring(tree, method='c14n', exclusive=False)
3400 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3401 s)
3402 s = etree.tostring(tree, method='c14n', exclusive=True)
3403 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3404 s)
3405
3406 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3407 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
3408 s)
3409
3411 tree = self.parse(_bytes(
3412 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3413 s = etree.tostring(tree.getroot(), method='c14n')
3414 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3415 s)
3416 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
3417 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3418 s)
3419 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
3420 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
3421 s)
3422
3423 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
3424 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3425 s)
3426 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
3427 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
3428 s)
3429
3430 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
3431 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
3432 s)
3433
3435 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
3436 tree = self.parse(_bytes(
3437 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
3438
3439 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
3440 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
3441 s)
3442
3443
3446 tree = self.parse(_bytes('<a><b/></a>'))
3447 f = BytesIO()
3448 tree.write(f)
3449 s = f.getvalue()
3450 self.assertEqual(_bytes('<a><b/></a>'),
3451 s)
3452
3454 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3455 f = BytesIO()
3456 tree.write(f, compression=9)
3457 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
3458 try:
3459 s = gzfile.read()
3460 finally:
3461 gzfile.close()
3462 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3463 s)
3464
3466 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3467 f = BytesIO()
3468 tree.write(f, compression=0)
3469 s0 = f.getvalue()
3470
3471 f = BytesIO()
3472 tree.write(f)
3473 self.assertEqual(f.getvalue(), s0)
3474
3475 f = BytesIO()
3476 tree.write(f, compression=1)
3477 s = f.getvalue()
3478 self.assertTrue(len(s) <= len(s0))
3479 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3480 try:
3481 s1 = gzfile.read()
3482 finally:
3483 gzfile.close()
3484
3485 f = BytesIO()
3486 tree.write(f, compression=9)
3487 s = f.getvalue()
3488 self.assertTrue(len(s) <= len(s0))
3489 gzfile = gzip.GzipFile(fileobj=BytesIO(s))
3490 try:
3491 s9 = gzfile.read()
3492 finally:
3493 gzfile.close()
3494
3495 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3496 s0)
3497 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3498 s1)
3499 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3500 s9)
3501
3503 tree = self.parse(_bytes('<a><b/></a>'))
3504 handle, filename = tempfile.mkstemp()
3505 try:
3506 tree.write(filename)
3507 data = read_file(filename, 'rb')
3508 finally:
3509 os.close(handle)
3510 os.remove(filename)
3511 self.assertEqual(_bytes('<a><b/></a>'),
3512 data)
3513
3515 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3516 handle, filename = tempfile.mkstemp()
3517 try:
3518 tree.write(filename, compression=9)
3519 f = gzip.open(filename, 'rb')
3520 try:
3521 data = f.read()
3522 finally:
3523 f.close()
3524 finally:
3525 os.close(handle)
3526 os.remove(filename)
3527 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3528 data)
3529
3531 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3532 handle, filename = tempfile.mkstemp()
3533 try:
3534 tree.write(filename, compression=9)
3535 data = etree.tostring(etree.parse(filename))
3536 finally:
3537 os.close(handle)
3538 os.remove(filename)
3539 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3540 data)
3541
3543 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
3544 handle, filename = tempfile.mkstemp()
3545 try:
3546 tree.write(filename, compression=9)
3547 data = etree.tostring(etree.parse(
3548 gzip.GzipFile(filename)))
3549 finally:
3550 os.close(handle)
3551 os.remove(filename)
3552 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'),
3553 data)
3554
3556 etree = etree
3557
3559 parse = self.etree.parse
3560 f = BytesIO('<a><b></c></b></a>')
3561 self.etree.clear_error_log()
3562 try:
3563 parse(f)
3564 logs = None
3565 except SyntaxError:
3566 e = sys.exc_info()[1]
3567 logs = e.error_log
3568 f.close()
3569 self.assertTrue([ log for log in logs
3570 if 'mismatch' in log.message ])
3571 self.assertTrue([ log for log in logs
3572 if 'PARSER' in log.domain_name])
3573 self.assertTrue([ log for log in logs
3574 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
3575 self.assertTrue([ log for log in logs
3576 if 1 == log.line ])
3577 self.assertTrue([ log for log in logs
3578 if 15 == log.column ])
3579
3590
3591 self.etree.use_global_python_log(Logger())
3592 f = BytesIO('<a><b></c></b></a>')
3593 try:
3594 parse(f)
3595 except SyntaxError:
3596 pass
3597 f.close()
3598
3599 self.assertTrue([ message for message in messages
3600 if 'mismatch' in message ])
3601 self.assertTrue([ message for message in messages
3602 if ':PARSER:' in message])
3603 self.assertTrue([ message for message in messages
3604 if ':ERR_TAG_NAME_MISMATCH:' in message ])
3605 self.assertTrue([ message for message in messages
3606 if ':1:15:' in message ])
3607
3609 suite = unittest.TestSuite()
3610 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
3611 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
3612 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
3613 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
3614 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
3615 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
3616 suite.addTests(
3617 [make_doctest('../../../doc/tutorial.txt')])
3618 suite.addTests(
3619 [make_doctest('../../../doc/api.txt')])
3620 suite.addTests(
3621 [make_doctest('../../../doc/FAQ.txt')])
3622 suite.addTests(
3623 [make_doctest('../../../doc/parsing.txt')])
3624 suite.addTests(
3625 [make_doctest('../../../doc/resolvers.txt')])
3626 return suite
3627
3628 if __name__ == '__main__':
3629 print('to test use test.py %s' % __file__)
3630
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Fri Dec 21 23:07:53 2012 | http://epydoc.sourceforge.net |