]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/test/test_xml_etree.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / test / test_xml_etree.py
CommitLineData
4710c53d 1# xml.etree test. This file contains enough tests to make sure that\r
2# all included components work as they should.\r
3# Large parts are extracted from the upstream test suite.\r
4\r
5# IMPORTANT: the same doctests are run from "test_xml_etree_c" in\r
6# order to ensure consistency between the C implementation and the\r
7# Python implementation.\r
8#\r
9# For this purpose, the module-level "ET" symbol is temporarily\r
10# monkey-patched when running the "test_xml_etree_c" test suite.\r
11# Don't re-import "xml.etree.ElementTree" module in the docstring,\r
12# except if the test is specific to the Python implementation.\r
13\r
14import sys\r
15import cgi\r
16\r
17from test import test_support\r
18from test.test_support import findfile\r
19\r
20from xml.etree import ElementTree as ET\r
21\r
22SIMPLE_XMLFILE = findfile("simple.xml", subdir="xmltestdata")\r
23SIMPLE_NS_XMLFILE = findfile("simple-ns.xml", subdir="xmltestdata")\r
24\r
25SAMPLE_XML = """\\r
26<body>\r
27 <tag class='a'>text</tag>\r
28 <tag class='b' />\r
29 <section>\r
30 <tag class='b' id='inner'>subtext</tag>\r
31 </section>\r
32</body>\r
33"""\r
34\r
35SAMPLE_SECTION = """\\r
36<section>\r
37 <tag class='b' id='inner'>subtext</tag>\r
38 <nexttag />\r
39 <nextsection>\r
40 <tag />\r
41 </nextsection>\r
42</section>\r
43"""\r
44\r
45SAMPLE_XML_NS = """\r
46<body xmlns="http://effbot.org/ns">\r
47 <tag>text</tag>\r
48 <tag />\r
49 <section>\r
50 <tag>subtext</tag>\r
51 </section>\r
52</body>\r
53"""\r
54\r
55\r
56def sanity():\r
57 """\r
58 Import sanity.\r
59\r
60 >>> from xml.etree import ElementTree\r
61 >>> from xml.etree import ElementInclude\r
62 >>> from xml.etree import ElementPath\r
63 """\r
64\r
65def check_method(method):\r
66 if not hasattr(method, '__call__'):\r
67 print method, "not callable"\r
68\r
69def serialize(elem, to_string=True, **options):\r
70 import StringIO\r
71 file = StringIO.StringIO()\r
72 tree = ET.ElementTree(elem)\r
73 tree.write(file, **options)\r
74 if to_string:\r
75 return file.getvalue()\r
76 else:\r
77 file.seek(0)\r
78 return file\r
79\r
80def summarize(elem):\r
81 if elem.tag == ET.Comment:\r
82 return "<Comment>"\r
83 return elem.tag\r
84\r
85def summarize_list(seq):\r
86 return [summarize(elem) for elem in seq]\r
87\r
88def normalize_crlf(tree):\r
89 for elem in tree.iter():\r
90 if elem.text:\r
91 elem.text = elem.text.replace("\r\n", "\n")\r
92 if elem.tail:\r
93 elem.tail = elem.tail.replace("\r\n", "\n")\r
94\r
95def check_string(string):\r
96 len(string)\r
97 for char in string:\r
98 if len(char) != 1:\r
99 print "expected one-character string, got %r" % char\r
100 new_string = string + ""\r
101 new_string = string + " "\r
102 string[:0]\r
103\r
104def check_mapping(mapping):\r
105 len(mapping)\r
106 keys = mapping.keys()\r
107 items = mapping.items()\r
108 for key in keys:\r
109 item = mapping[key]\r
110 mapping["key"] = "value"\r
111 if mapping["key"] != "value":\r
112 print "expected value string, got %r" % mapping["key"]\r
113\r
114def check_element(element):\r
115 if not ET.iselement(element):\r
116 print "not an element"\r
117 if not hasattr(element, "tag"):\r
118 print "no tag member"\r
119 if not hasattr(element, "attrib"):\r
120 print "no attrib member"\r
121 if not hasattr(element, "text"):\r
122 print "no text member"\r
123 if not hasattr(element, "tail"):\r
124 print "no tail member"\r
125\r
126 check_string(element.tag)\r
127 check_mapping(element.attrib)\r
128 if element.text is not None:\r
129 check_string(element.text)\r
130 if element.tail is not None:\r
131 check_string(element.tail)\r
132 for elem in element:\r
133 check_element(elem)\r
134\r
135# --------------------------------------------------------------------\r
136# element tree tests\r
137\r
138def interface():\r
139 r"""\r
140 Test element tree interface.\r
141\r
142 >>> element = ET.Element("tag")\r
143 >>> check_element(element)\r
144 >>> tree = ET.ElementTree(element)\r
145 >>> check_element(tree.getroot())\r
146\r
147 >>> element = ET.Element("t\xe4g", key="value")\r
148 >>> tree = ET.ElementTree(element)\r
149 >>> repr(element) # doctest: +ELLIPSIS\r
150 "<Element 't\\xe4g' at 0x...>"\r
151 >>> element = ET.Element("tag", key="value")\r
152\r
153 Make sure all standard element methods exist.\r
154\r
155 >>> check_method(element.append)\r
156 >>> check_method(element.extend)\r
157 >>> check_method(element.insert)\r
158 >>> check_method(element.remove)\r
159 >>> check_method(element.getchildren)\r
160 >>> check_method(element.find)\r
161 >>> check_method(element.iterfind)\r
162 >>> check_method(element.findall)\r
163 >>> check_method(element.findtext)\r
164 >>> check_method(element.clear)\r
165 >>> check_method(element.get)\r
166 >>> check_method(element.set)\r
167 >>> check_method(element.keys)\r
168 >>> check_method(element.items)\r
169 >>> check_method(element.iter)\r
170 >>> check_method(element.itertext)\r
171 >>> check_method(element.getiterator)\r
172\r
173 These methods return an iterable. See bug 6472.\r
174\r
175 >>> check_method(element.iter("tag").next)\r
176 >>> check_method(element.iterfind("tag").next)\r
177 >>> check_method(element.iterfind("*").next)\r
178 >>> check_method(tree.iter("tag").next)\r
179 >>> check_method(tree.iterfind("tag").next)\r
180 >>> check_method(tree.iterfind("*").next)\r
181\r
182 These aliases are provided:\r
183\r
184 >>> assert ET.XML == ET.fromstring\r
185 >>> assert ET.PI == ET.ProcessingInstruction\r
186 >>> assert ET.XMLParser == ET.XMLTreeBuilder\r
187 """\r
188\r
189def simpleops():\r
190 """\r
191 Basic method sanity checks.\r
192\r
193 >>> elem = ET.XML("<body><tag/></body>")\r
194 >>> serialize(elem)\r
195 '<body><tag /></body>'\r
196 >>> e = ET.Element("tag2")\r
197 >>> elem.append(e)\r
198 >>> serialize(elem)\r
199 '<body><tag /><tag2 /></body>'\r
200 >>> elem.remove(e)\r
201 >>> serialize(elem)\r
202 '<body><tag /></body>'\r
203 >>> elem.insert(0, e)\r
204 >>> serialize(elem)\r
205 '<body><tag2 /><tag /></body>'\r
206 >>> elem.remove(e)\r
207 >>> elem.extend([e])\r
208 >>> serialize(elem)\r
209 '<body><tag /><tag2 /></body>'\r
210 >>> elem.remove(e)\r
211\r
212 >>> element = ET.Element("tag", key="value")\r
213 >>> serialize(element) # 1\r
214 '<tag key="value" />'\r
215 >>> subelement = ET.Element("subtag")\r
216 >>> element.append(subelement)\r
217 >>> serialize(element) # 2\r
218 '<tag key="value"><subtag /></tag>'\r
219 >>> element.insert(0, subelement)\r
220 >>> serialize(element) # 3\r
221 '<tag key="value"><subtag /><subtag /></tag>'\r
222 >>> element.remove(subelement)\r
223 >>> serialize(element) # 4\r
224 '<tag key="value"><subtag /></tag>'\r
225 >>> element.remove(subelement)\r
226 >>> serialize(element) # 5\r
227 '<tag key="value" />'\r
228 >>> element.remove(subelement)\r
229 Traceback (most recent call last):\r
230 ValueError: list.remove(x): x not in list\r
231 >>> serialize(element) # 6\r
232 '<tag key="value" />'\r
233 >>> element[0:0] = [subelement, subelement, subelement]\r
234 >>> serialize(element[1])\r
235 '<subtag />'\r
236 >>> element[1:9] == [element[1], element[2]]\r
237 True\r
238 >>> element[:9:2] == [element[0], element[2]]\r
239 True\r
240 >>> del element[1:2]\r
241 >>> serialize(element)\r
242 '<tag key="value"><subtag /><subtag /></tag>'\r
243 """\r
244\r
245def cdata():\r
246 """\r
247 Test CDATA handling (etc).\r
248\r
249 >>> serialize(ET.XML("<tag>hello</tag>"))\r
250 '<tag>hello</tag>'\r
251 >>> serialize(ET.XML("<tag>&#104;&#101;&#108;&#108;&#111;</tag>"))\r
252 '<tag>hello</tag>'\r
253 >>> serialize(ET.XML("<tag><![CDATA[hello]]></tag>"))\r
254 '<tag>hello</tag>'\r
255 """\r
256\r
257# Only with Python implementation\r
258def simplefind():\r
259 """\r
260 Test find methods using the elementpath fallback.\r
261\r
262 >>> from xml.etree import ElementTree\r
263\r
264 >>> CurrentElementPath = ElementTree.ElementPath\r
265 >>> ElementTree.ElementPath = ElementTree._SimpleElementPath()\r
266 >>> elem = ElementTree.XML(SAMPLE_XML)\r
267 >>> elem.find("tag").tag\r
268 'tag'\r
269 >>> ElementTree.ElementTree(elem).find("tag").tag\r
270 'tag'\r
271 >>> elem.findtext("tag")\r
272 'text'\r
273 >>> elem.findtext("tog")\r
274 >>> elem.findtext("tog", "default")\r
275 'default'\r
276 >>> ElementTree.ElementTree(elem).findtext("tag")\r
277 'text'\r
278 >>> summarize_list(elem.findall("tag"))\r
279 ['tag', 'tag']\r
280 >>> summarize_list(elem.findall(".//tag"))\r
281 ['tag', 'tag', 'tag']\r
282\r
283 Path syntax doesn't work in this case.\r
284\r
285 >>> elem.find("section/tag")\r
286 >>> elem.findtext("section/tag")\r
287 >>> summarize_list(elem.findall("section/tag"))\r
288 []\r
289\r
290 >>> ElementTree.ElementPath = CurrentElementPath\r
291 """\r
292\r
293def find():\r
294 """\r
295 Test find methods (including xpath syntax).\r
296\r
297 >>> elem = ET.XML(SAMPLE_XML)\r
298 >>> elem.find("tag").tag\r
299 'tag'\r
300 >>> ET.ElementTree(elem).find("tag").tag\r
301 'tag'\r
302 >>> elem.find("section/tag").tag\r
303 'tag'\r
304 >>> elem.find("./tag").tag\r
305 'tag'\r
306 >>> ET.ElementTree(elem).find("./tag").tag\r
307 'tag'\r
308 >>> ET.ElementTree(elem).find("/tag").tag\r
309 'tag'\r
310 >>> elem[2] = ET.XML(SAMPLE_SECTION)\r
311 >>> elem.find("section/nexttag").tag\r
312 'nexttag'\r
313 >>> ET.ElementTree(elem).find("section/tag").tag\r
314 'tag'\r
315 >>> ET.ElementTree(elem).find("tog")\r
316 >>> ET.ElementTree(elem).find("tog/foo")\r
317 >>> elem.findtext("tag")\r
318 'text'\r
319 >>> elem.findtext("section/nexttag")\r
320 ''\r
321 >>> elem.findtext("section/nexttag", "default")\r
322 ''\r
323 >>> elem.findtext("tog")\r
324 >>> elem.findtext("tog", "default")\r
325 'default'\r
326 >>> ET.ElementTree(elem).findtext("tag")\r
327 'text'\r
328 >>> ET.ElementTree(elem).findtext("tog/foo")\r
329 >>> ET.ElementTree(elem).findtext("tog/foo", "default")\r
330 'default'\r
331 >>> ET.ElementTree(elem).findtext("./tag")\r
332 'text'\r
333 >>> ET.ElementTree(elem).findtext("/tag")\r
334 'text'\r
335 >>> elem.findtext("section/tag")\r
336 'subtext'\r
337 >>> ET.ElementTree(elem).findtext("section/tag")\r
338 'subtext'\r
339 >>> summarize_list(elem.findall("."))\r
340 ['body']\r
341 >>> summarize_list(elem.findall("tag"))\r
342 ['tag', 'tag']\r
343 >>> summarize_list(elem.findall("tog"))\r
344 []\r
345 >>> summarize_list(elem.findall("tog/foo"))\r
346 []\r
347 >>> summarize_list(elem.findall("*"))\r
348 ['tag', 'tag', 'section']\r
349 >>> summarize_list(elem.findall(".//tag"))\r
350 ['tag', 'tag', 'tag', 'tag']\r
351 >>> summarize_list(elem.findall("section/tag"))\r
352 ['tag']\r
353 >>> summarize_list(elem.findall("section//tag"))\r
354 ['tag', 'tag']\r
355 >>> summarize_list(elem.findall("section/*"))\r
356 ['tag', 'nexttag', 'nextsection']\r
357 >>> summarize_list(elem.findall("section//*"))\r
358 ['tag', 'nexttag', 'nextsection', 'tag']\r
359 >>> summarize_list(elem.findall("section/.//*"))\r
360 ['tag', 'nexttag', 'nextsection', 'tag']\r
361 >>> summarize_list(elem.findall("*/*"))\r
362 ['tag', 'nexttag', 'nextsection']\r
363 >>> summarize_list(elem.findall("*//*"))\r
364 ['tag', 'nexttag', 'nextsection', 'tag']\r
365 >>> summarize_list(elem.findall("*/tag"))\r
366 ['tag']\r
367 >>> summarize_list(elem.findall("*/./tag"))\r
368 ['tag']\r
369 >>> summarize_list(elem.findall("./tag"))\r
370 ['tag', 'tag']\r
371 >>> summarize_list(elem.findall(".//tag"))\r
372 ['tag', 'tag', 'tag', 'tag']\r
373 >>> summarize_list(elem.findall("././tag"))\r
374 ['tag', 'tag']\r
375 >>> summarize_list(elem.findall(".//tag[@class]"))\r
376 ['tag', 'tag', 'tag']\r
377 >>> summarize_list(elem.findall(".//tag[@class='a']"))\r
378 ['tag']\r
379 >>> summarize_list(elem.findall(".//tag[@class='b']"))\r
380 ['tag', 'tag']\r
381 >>> summarize_list(elem.findall(".//tag[@id]"))\r
382 ['tag']\r
383 >>> summarize_list(elem.findall(".//section[tag]"))\r
384 ['section']\r
385 >>> summarize_list(elem.findall(".//section[element]"))\r
386 []\r
387 >>> summarize_list(elem.findall("../tag"))\r
388 []\r
389 >>> summarize_list(elem.findall("section/../tag"))\r
390 ['tag', 'tag']\r
391 >>> summarize_list(ET.ElementTree(elem).findall("./tag"))\r
392 ['tag', 'tag']\r
393\r
394 Following example is invalid in 1.2.\r
395 A leading '*' is assumed in 1.3.\r
396\r
397 >>> elem.findall("section//") == elem.findall("section//*")\r
398 True\r
399\r
400 ET's Path module handles this case incorrectly; this gives\r
401 a warning in 1.3, and the behaviour will be modified in 1.4.\r
402\r
403 >>> summarize_list(ET.ElementTree(elem).findall("/tag"))\r
404 ['tag', 'tag']\r
405\r
406 >>> elem = ET.XML(SAMPLE_XML_NS)\r
407 >>> summarize_list(elem.findall("tag"))\r
408 []\r
409 >>> summarize_list(elem.findall("{http://effbot.org/ns}tag"))\r
410 ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag']\r
411 >>> summarize_list(elem.findall(".//{http://effbot.org/ns}tag"))\r
412 ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag']\r
413 """\r
414\r
415def file_init():\r
416 """\r
417 >>> import StringIO\r
418\r
419 >>> stringfile = StringIO.StringIO(SAMPLE_XML)\r
420 >>> tree = ET.ElementTree(file=stringfile)\r
421 >>> tree.find("tag").tag\r
422 'tag'\r
423 >>> tree.find("section/tag").tag\r
424 'tag'\r
425\r
426 >>> tree = ET.ElementTree(file=SIMPLE_XMLFILE)\r
427 >>> tree.find("element").tag\r
428 'element'\r
429 >>> tree.find("element/../empty-element").tag\r
430 'empty-element'\r
431 """\r
432\r
433def bad_find():\r
434 """\r
435 Check bad or unsupported path expressions.\r
436\r
437 >>> elem = ET.XML(SAMPLE_XML)\r
438 >>> elem.findall("/tag")\r
439 Traceback (most recent call last):\r
440 SyntaxError: cannot use absolute path on element\r
441 """\r
442\r
443def path_cache():\r
444 """\r
445 Check that the path cache behaves sanely.\r
446\r
447 >>> elem = ET.XML(SAMPLE_XML)\r
448 >>> for i in range(10): ET.ElementTree(elem).find('./'+str(i))\r
449 >>> cache_len_10 = len(ET.ElementPath._cache)\r
450 >>> for i in range(10): ET.ElementTree(elem).find('./'+str(i))\r
451 >>> len(ET.ElementPath._cache) == cache_len_10\r
452 True\r
453 >>> for i in range(20): ET.ElementTree(elem).find('./'+str(i))\r
454 >>> len(ET.ElementPath._cache) > cache_len_10\r
455 True\r
456 >>> for i in range(600): ET.ElementTree(elem).find('./'+str(i))\r
457 >>> len(ET.ElementPath._cache) < 500\r
458 True\r
459 """\r
460\r
461def copy():\r
462 """\r
463 Test copy handling (etc).\r
464\r
465 >>> import copy\r
466 >>> e1 = ET.XML("<tag>hello<foo/></tag>")\r
467 >>> e2 = copy.copy(e1)\r
468 >>> e3 = copy.deepcopy(e1)\r
469 >>> e1.find("foo").tag = "bar"\r
470 >>> serialize(e1)\r
471 '<tag>hello<bar /></tag>'\r
472 >>> serialize(e2)\r
473 '<tag>hello<bar /></tag>'\r
474 >>> serialize(e3)\r
475 '<tag>hello<foo /></tag>'\r
476\r
477 """\r
478\r
479def attrib():\r
480 """\r
481 Test attribute handling.\r
482\r
483 >>> elem = ET.Element("tag")\r
484 >>> elem.get("key") # 1.1\r
485 >>> elem.get("key", "default") # 1.2\r
486 'default'\r
487 >>> elem.set("key", "value")\r
488 >>> elem.get("key") # 1.3\r
489 'value'\r
490\r
491 >>> elem = ET.Element("tag", key="value")\r
492 >>> elem.get("key") # 2.1\r
493 'value'\r
494 >>> elem.attrib # 2.2\r
495 {'key': 'value'}\r
496\r
497 >>> attrib = {"key": "value"}\r
498 >>> elem = ET.Element("tag", attrib)\r
499 >>> attrib.clear() # check for aliasing issues\r
500 >>> elem.get("key") # 3.1\r
501 'value'\r
502 >>> elem.attrib # 3.2\r
503 {'key': 'value'}\r
504\r
505 >>> attrib = {"key": "value"}\r
506 >>> elem = ET.Element("tag", **attrib)\r
507 >>> attrib.clear() # check for aliasing issues\r
508 >>> elem.get("key") # 4.1\r
509 'value'\r
510 >>> elem.attrib # 4.2\r
511 {'key': 'value'}\r
512\r
513 >>> elem = ET.Element("tag", {"key": "other"}, key="value")\r
514 >>> elem.get("key") # 5.1\r
515 'value'\r
516 >>> elem.attrib # 5.2\r
517 {'key': 'value'}\r
518\r
519 >>> elem = ET.Element('test')\r
520 >>> elem.text = "aa"\r
521 >>> elem.set('testa', 'testval')\r
522 >>> elem.set('testb', 'test2')\r
523 >>> ET.tostring(elem)\r
524 '<test testa="testval" testb="test2">aa</test>'\r
525 >>> sorted(elem.keys())\r
526 ['testa', 'testb']\r
527 >>> sorted(elem.items())\r
528 [('testa', 'testval'), ('testb', 'test2')]\r
529 >>> elem.attrib['testb']\r
530 'test2'\r
531 >>> elem.attrib['testb'] = 'test1'\r
532 >>> elem.attrib['testc'] = 'test2'\r
533 >>> ET.tostring(elem)\r
534 '<test testa="testval" testb="test1" testc="test2">aa</test>'\r
535 """\r
536\r
537def makeelement():\r
538 """\r
539 Test makeelement handling.\r
540\r
541 >>> elem = ET.Element("tag")\r
542 >>> attrib = {"key": "value"}\r
543 >>> subelem = elem.makeelement("subtag", attrib)\r
544 >>> if subelem.attrib is attrib:\r
545 ... print "attrib aliasing"\r
546 >>> elem.append(subelem)\r
547 >>> serialize(elem)\r
548 '<tag><subtag key="value" /></tag>'\r
549\r
550 >>> elem.clear()\r
551 >>> serialize(elem)\r
552 '<tag />'\r
553 >>> elem.append(subelem)\r
554 >>> serialize(elem)\r
555 '<tag><subtag key="value" /></tag>'\r
556 >>> elem.extend([subelem, subelem])\r
557 >>> serialize(elem)\r
558 '<tag><subtag key="value" /><subtag key="value" /><subtag key="value" /></tag>'\r
559 >>> elem[:] = [subelem]\r
560 >>> serialize(elem)\r
561 '<tag><subtag key="value" /></tag>'\r
562 >>> elem[:] = tuple([subelem])\r
563 >>> serialize(elem)\r
564 '<tag><subtag key="value" /></tag>'\r
565\r
566 """\r
567\r
568def parsefile():\r
569 """\r
570 Test parsing from file.\r
571\r
572 >>> tree = ET.parse(SIMPLE_XMLFILE)\r
573 >>> normalize_crlf(tree)\r
574 >>> tree.write(sys.stdout)\r
575 <root>\r
576 <element key="value">text</element>\r
577 <element>text</element>tail\r
578 <empty-element />\r
579 </root>\r
580 >>> tree = ET.parse(SIMPLE_NS_XMLFILE)\r
581 >>> normalize_crlf(tree)\r
582 >>> tree.write(sys.stdout)\r
583 <ns0:root xmlns:ns0="namespace">\r
584 <ns0:element key="value">text</ns0:element>\r
585 <ns0:element>text</ns0:element>tail\r
586 <ns0:empty-element />\r
587 </ns0:root>\r
588\r
589 >>> with open(SIMPLE_XMLFILE) as f:\r
590 ... data = f.read()\r
591\r
592 >>> parser = ET.XMLParser()\r
593 >>> parser.version # doctest: +ELLIPSIS\r
594 'Expat ...'\r
595 >>> parser.feed(data)\r
596 >>> print serialize(parser.close())\r
597 <root>\r
598 <element key="value">text</element>\r
599 <element>text</element>tail\r
600 <empty-element />\r
601 </root>\r
602\r
603 >>> parser = ET.XMLTreeBuilder() # 1.2 compatibility\r
604 >>> parser.feed(data)\r
605 >>> print serialize(parser.close())\r
606 <root>\r
607 <element key="value">text</element>\r
608 <element>text</element>tail\r
609 <empty-element />\r
610 </root>\r
611\r
612 >>> target = ET.TreeBuilder()\r
613 >>> parser = ET.XMLParser(target=target)\r
614 >>> parser.feed(data)\r
615 >>> print serialize(parser.close())\r
616 <root>\r
617 <element key="value">text</element>\r
618 <element>text</element>tail\r
619 <empty-element />\r
620 </root>\r
621 """\r
622\r
623def parseliteral():\r
624 """\r
625 >>> element = ET.XML("<html><body>text</body></html>")\r
626 >>> ET.ElementTree(element).write(sys.stdout)\r
627 <html><body>text</body></html>\r
628 >>> element = ET.fromstring("<html><body>text</body></html>")\r
629 >>> ET.ElementTree(element).write(sys.stdout)\r
630 <html><body>text</body></html>\r
631 >>> sequence = ["<html><body>", "text</bo", "dy></html>"]\r
632 >>> element = ET.fromstringlist(sequence)\r
633 >>> print ET.tostring(element)\r
634 <html><body>text</body></html>\r
635 >>> print "".join(ET.tostringlist(element))\r
636 <html><body>text</body></html>\r
637 >>> ET.tostring(element, "ascii")\r
638 "<?xml version='1.0' encoding='ascii'?>\\n<html><body>text</body></html>"\r
639 >>> _, ids = ET.XMLID("<html><body>text</body></html>")\r
640 >>> len(ids)\r
641 0\r
642 >>> _, ids = ET.XMLID("<html><body id='body'>text</body></html>")\r
643 >>> len(ids)\r
644 1\r
645 >>> ids["body"].tag\r
646 'body'\r
647 """\r
648\r
649def iterparse():\r
650 """\r
651 Test iterparse interface.\r
652\r
653 >>> iterparse = ET.iterparse\r
654\r
655 >>> context = iterparse(SIMPLE_XMLFILE)\r
656 >>> action, elem = next(context)\r
657 >>> print action, elem.tag\r
658 end element\r
659 >>> for action, elem in context:\r
660 ... print action, elem.tag\r
661 end element\r
662 end empty-element\r
663 end root\r
664 >>> context.root.tag\r
665 'root'\r
666\r
667 >>> context = iterparse(SIMPLE_NS_XMLFILE)\r
668 >>> for action, elem in context:\r
669 ... print action, elem.tag\r
670 end {namespace}element\r
671 end {namespace}element\r
672 end {namespace}empty-element\r
673 end {namespace}root\r
674\r
675 >>> events = ()\r
676 >>> context = iterparse(SIMPLE_XMLFILE, events)\r
677 >>> for action, elem in context:\r
678 ... print action, elem.tag\r
679\r
680 >>> events = ()\r
681 >>> context = iterparse(SIMPLE_XMLFILE, events=events)\r
682 >>> for action, elem in context:\r
683 ... print action, elem.tag\r
684\r
685 >>> events = ("start", "end")\r
686 >>> context = iterparse(SIMPLE_XMLFILE, events)\r
687 >>> for action, elem in context:\r
688 ... print action, elem.tag\r
689 start root\r
690 start element\r
691 end element\r
692 start element\r
693 end element\r
694 start empty-element\r
695 end empty-element\r
696 end root\r
697\r
698 >>> events = ("start", "end", "start-ns", "end-ns")\r
699 >>> context = iterparse(SIMPLE_NS_XMLFILE, events)\r
700 >>> for action, elem in context:\r
701 ... if action in ("start", "end"):\r
702 ... print action, elem.tag\r
703 ... else:\r
704 ... print action, elem\r
705 start-ns ('', 'namespace')\r
706 start {namespace}root\r
707 start {namespace}element\r
708 end {namespace}element\r
709 start {namespace}element\r
710 end {namespace}element\r
711 start {namespace}empty-element\r
712 end {namespace}empty-element\r
713 end {namespace}root\r
714 end-ns None\r
715\r
716 >>> events = ("start", "end", "bogus")\r
717 >>> with open(SIMPLE_XMLFILE, "rb") as f:\r
718 ... iterparse(f, events)\r
719 Traceback (most recent call last):\r
720 ValueError: unknown event 'bogus'\r
721\r
722 >>> import StringIO\r
723\r
724 >>> source = StringIO.StringIO(\r
725 ... "<?xml version='1.0' encoding='iso-8859-1'?>\\n"\r
726 ... "<body xmlns='http://&#233;ffbot.org/ns'\\n"\r
727 ... " xmlns:cl\\xe9='http://effbot.org/ns'>text</body>\\n")\r
728 >>> events = ("start-ns",)\r
729 >>> context = iterparse(source, events)\r
730 >>> for action, elem in context:\r
731 ... print action, elem\r
732 start-ns ('', u'http://\\xe9ffbot.org/ns')\r
733 start-ns (u'cl\\xe9', 'http://effbot.org/ns')\r
734\r
735 >>> source = StringIO.StringIO("<document />junk")\r
736 >>> try:\r
737 ... for action, elem in iterparse(source):\r
738 ... print action, elem.tag\r
739 ... except ET.ParseError, v:\r
740 ... print v\r
741 junk after document element: line 1, column 12\r
742 """\r
743\r
744def writefile():\r
745 """\r
746 >>> elem = ET.Element("tag")\r
747 >>> elem.text = "text"\r
748 >>> serialize(elem)\r
749 '<tag>text</tag>'\r
750 >>> ET.SubElement(elem, "subtag").text = "subtext"\r
751 >>> serialize(elem)\r
752 '<tag>text<subtag>subtext</subtag></tag>'\r
753\r
754 Test tag suppression\r
755 >>> elem.tag = None\r
756 >>> serialize(elem)\r
757 'text<subtag>subtext</subtag>'\r
758 >>> elem.insert(0, ET.Comment("comment"))\r
759 >>> serialize(elem) # assumes 1.3\r
760 'text<!--comment--><subtag>subtext</subtag>'\r
761 >>> elem[0] = ET.PI("key", "value")\r
762 >>> serialize(elem)\r
763 'text<?key value?><subtag>subtext</subtag>'\r
764 """\r
765\r
766def custom_builder():\r
767 """\r
768 Test parser w. custom builder.\r
769\r
770 >>> with open(SIMPLE_XMLFILE) as f:\r
771 ... data = f.read()\r
772 >>> class Builder:\r
773 ... def start(self, tag, attrib):\r
774 ... print "start", tag\r
775 ... def end(self, tag):\r
776 ... print "end", tag\r
777 ... def data(self, text):\r
778 ... pass\r
779 >>> builder = Builder()\r
780 >>> parser = ET.XMLParser(target=builder)\r
781 >>> parser.feed(data)\r
782 start root\r
783 start element\r
784 end element\r
785 start element\r
786 end element\r
787 start empty-element\r
788 end empty-element\r
789 end root\r
790\r
791 >>> with open(SIMPLE_NS_XMLFILE) as f:\r
792 ... data = f.read()\r
793 >>> class Builder:\r
794 ... def start(self, tag, attrib):\r
795 ... print "start", tag\r
796 ... def end(self, tag):\r
797 ... print "end", tag\r
798 ... def data(self, text):\r
799 ... pass\r
800 ... def pi(self, target, data):\r
801 ... print "pi", target, repr(data)\r
802 ... def comment(self, data):\r
803 ... print "comment", repr(data)\r
804 >>> builder = Builder()\r
805 >>> parser = ET.XMLParser(target=builder)\r
806 >>> parser.feed(data)\r
807 pi pi 'data'\r
808 comment ' comment '\r
809 start {namespace}root\r
810 start {namespace}element\r
811 end {namespace}element\r
812 start {namespace}element\r
813 end {namespace}element\r
814 start {namespace}empty-element\r
815 end {namespace}empty-element\r
816 end {namespace}root\r
817\r
818 """\r
819\r
820def getchildren():\r
821 """\r
822 Test Element.getchildren()\r
823\r
824 >>> with open(SIMPLE_XMLFILE, "r") as f:\r
825 ... tree = ET.parse(f)\r
826 >>> for elem in tree.getroot().iter():\r
827 ... summarize_list(elem.getchildren())\r
828 ['element', 'element', 'empty-element']\r
829 []\r
830 []\r
831 []\r
832 >>> for elem in tree.getiterator():\r
833 ... summarize_list(elem.getchildren())\r
834 ['element', 'element', 'empty-element']\r
835 []\r
836 []\r
837 []\r
838\r
839 >>> elem = ET.XML(SAMPLE_XML)\r
840 >>> len(elem.getchildren())\r
841 3\r
842 >>> len(elem[2].getchildren())\r
843 1\r
844 >>> elem[:] == elem.getchildren()\r
845 True\r
846 >>> child1 = elem[0]\r
847 >>> child2 = elem[2]\r
848 >>> del elem[1:2]\r
849 >>> len(elem.getchildren())\r
850 2\r
851 >>> child1 == elem[0]\r
852 True\r
853 >>> child2 == elem[1]\r
854 True\r
855 >>> elem[0:2] = [child2, child1]\r
856 >>> child2 == elem[0]\r
857 True\r
858 >>> child1 == elem[1]\r
859 True\r
860 >>> child1 == elem[0]\r
861 False\r
862 >>> elem.clear()\r
863 >>> elem.getchildren()\r
864 []\r
865 """\r
866\r
867def writestring():\r
868 """\r
869 >>> elem = ET.XML("<html><body>text</body></html>")\r
870 >>> ET.tostring(elem)\r
871 '<html><body>text</body></html>'\r
872 >>> elem = ET.fromstring("<html><body>text</body></html>")\r
873 >>> ET.tostring(elem)\r
874 '<html><body>text</body></html>'\r
875 """\r
876\r
877def check_encoding(encoding):\r
878 """\r
879 >>> check_encoding("ascii")\r
880 >>> check_encoding("us-ascii")\r
881 >>> check_encoding("iso-8859-1")\r
882 >>> check_encoding("iso-8859-15")\r
883 >>> check_encoding("cp437")\r
884 >>> check_encoding("mac-roman")\r
885 """\r
886 ET.XML("<?xml version='1.0' encoding='%s'?><xml />" % encoding)\r
887\r
888def encoding():\r
889 r"""\r
890 Test encoding issues.\r
891\r
892 >>> elem = ET.Element("tag")\r
893 >>> elem.text = u"abc"\r
894 >>> serialize(elem)\r
895 '<tag>abc</tag>'\r
896 >>> serialize(elem, encoding="utf-8")\r
897 '<tag>abc</tag>'\r
898 >>> serialize(elem, encoding="us-ascii")\r
899 '<tag>abc</tag>'\r
900 >>> serialize(elem, encoding="iso-8859-1")\r
901 "<?xml version='1.0' encoding='iso-8859-1'?>\n<tag>abc</tag>"\r
902\r
903 >>> elem.text = "<&\"\'>"\r
904 >>> serialize(elem)\r
905 '<tag>&lt;&amp;"\'&gt;</tag>'\r
906 >>> serialize(elem, encoding="utf-8")\r
907 '<tag>&lt;&amp;"\'&gt;</tag>'\r
908 >>> serialize(elem, encoding="us-ascii") # cdata characters\r
909 '<tag>&lt;&amp;"\'&gt;</tag>'\r
910 >>> serialize(elem, encoding="iso-8859-1")\r
911 '<?xml version=\'1.0\' encoding=\'iso-8859-1\'?>\n<tag>&lt;&amp;"\'&gt;</tag>'\r
912\r
913 >>> elem.attrib["key"] = "<&\"\'>"\r
914 >>> elem.text = None\r
915 >>> serialize(elem)\r
916 '<tag key="&lt;&amp;&quot;\'&gt;" />'\r
917 >>> serialize(elem, encoding="utf-8")\r
918 '<tag key="&lt;&amp;&quot;\'&gt;" />'\r
919 >>> serialize(elem, encoding="us-ascii")\r
920 '<tag key="&lt;&amp;&quot;\'&gt;" />'\r
921 >>> serialize(elem, encoding="iso-8859-1")\r
922 '<?xml version=\'1.0\' encoding=\'iso-8859-1\'?>\n<tag key="&lt;&amp;&quot;\'&gt;" />'\r
923\r
924 >>> elem.text = u'\xe5\xf6\xf6<>'\r
925 >>> elem.attrib.clear()\r
926 >>> serialize(elem)\r
927 '<tag>&#229;&#246;&#246;&lt;&gt;</tag>'\r
928 >>> serialize(elem, encoding="utf-8")\r
929 '<tag>\xc3\xa5\xc3\xb6\xc3\xb6&lt;&gt;</tag>'\r
930 >>> serialize(elem, encoding="us-ascii")\r
931 '<tag>&#229;&#246;&#246;&lt;&gt;</tag>'\r
932 >>> serialize(elem, encoding="iso-8859-1")\r
933 "<?xml version='1.0' encoding='iso-8859-1'?>\n<tag>\xe5\xf6\xf6&lt;&gt;</tag>"\r
934\r
935 >>> elem.attrib["key"] = u'\xe5\xf6\xf6<>'\r
936 >>> elem.text = None\r
937 >>> serialize(elem)\r
938 '<tag key="&#229;&#246;&#246;&lt;&gt;" />'\r
939 >>> serialize(elem, encoding="utf-8")\r
940 '<tag key="\xc3\xa5\xc3\xb6\xc3\xb6&lt;&gt;" />'\r
941 >>> serialize(elem, encoding="us-ascii")\r
942 '<tag key="&#229;&#246;&#246;&lt;&gt;" />'\r
943 >>> serialize(elem, encoding="iso-8859-1")\r
944 '<?xml version=\'1.0\' encoding=\'iso-8859-1\'?>\n<tag key="\xe5\xf6\xf6&lt;&gt;" />'\r
945 """\r
946\r
947def methods():\r
948 r"""\r
949 Test serialization methods.\r
950\r
951 >>> e = ET.XML("<html><link/><script>1 &lt; 2</script></html>")\r
952 >>> e.tail = "\n"\r
953 >>> serialize(e)\r
954 '<html><link /><script>1 &lt; 2</script></html>\n'\r
955 >>> serialize(e, method=None)\r
956 '<html><link /><script>1 &lt; 2</script></html>\n'\r
957 >>> serialize(e, method="xml")\r
958 '<html><link /><script>1 &lt; 2</script></html>\n'\r
959 >>> serialize(e, method="html")\r
960 '<html><link><script>1 < 2</script></html>\n'\r
961 >>> serialize(e, method="text")\r
962 '1 < 2\n'\r
963 """\r
964\r
965def iterators():\r
966 """\r
967 Test iterators.\r
968\r
969 >>> e = ET.XML("<html><body>this is a <i>paragraph</i>.</body>..</html>")\r
970 >>> summarize_list(e.iter())\r
971 ['html', 'body', 'i']\r
972 >>> summarize_list(e.find("body").iter())\r
973 ['body', 'i']\r
974 >>> summarize(next(e.iter()))\r
975 'html'\r
976 >>> "".join(e.itertext())\r
977 'this is a paragraph...'\r
978 >>> "".join(e.find("body").itertext())\r
979 'this is a paragraph.'\r
980 >>> next(e.itertext())\r
981 'this is a '\r
982\r
983 Method iterparse should return an iterator. See bug 6472.\r
984\r
985 >>> sourcefile = serialize(e, to_string=False)\r
986 >>> next(ET.iterparse(sourcefile)) # doctest: +ELLIPSIS\r
987 ('end', <Element 'i' at 0x...>)\r
988\r
989 >>> tree = ET.ElementTree(None)\r
990 >>> tree.iter()\r
991 Traceback (most recent call last):\r
992 AttributeError: 'NoneType' object has no attribute 'iter'\r
993 """\r
994\r
995ENTITY_XML = """\\r
996<!DOCTYPE points [\r
997<!ENTITY % user-entities SYSTEM 'user-entities.xml'>\r
998%user-entities;\r
999]>\r
1000<document>&entity;</document>\r
1001"""\r
1002\r
1003def entity():\r
1004 """\r
1005 Test entity handling.\r
1006\r
1007 1) good entities\r
1008\r
1009 >>> e = ET.XML("<document title='&#x8230;'>test</document>")\r
1010 >>> serialize(e)\r
1011 '<document title="&#33328;">test</document>'\r
1012\r
1013 2) bad entities\r
1014\r
1015 >>> ET.XML("<document>&entity;</document>")\r
1016 Traceback (most recent call last):\r
1017 ParseError: undefined entity: line 1, column 10\r
1018\r
1019 >>> ET.XML(ENTITY_XML)\r
1020 Traceback (most recent call last):\r
1021 ParseError: undefined entity &entity;: line 5, column 10\r
1022\r
1023 3) custom entity\r
1024\r
1025 >>> parser = ET.XMLParser()\r
1026 >>> parser.entity["entity"] = "text"\r
1027 >>> parser.feed(ENTITY_XML)\r
1028 >>> root = parser.close()\r
1029 >>> serialize(root)\r
1030 '<document>text</document>'\r
1031 """\r
1032\r
1033def error(xml):\r
1034 """\r
1035\r
1036 Test error handling.\r
1037\r
1038 >>> issubclass(ET.ParseError, SyntaxError)\r
1039 True\r
1040 >>> error("foo").position\r
1041 (1, 0)\r
1042 >>> error("<tag>&foo;</tag>").position\r
1043 (1, 5)\r
1044 >>> error("foobar<").position\r
1045 (1, 6)\r
1046\r
1047 """\r
1048 try:\r
1049 ET.XML(xml)\r
1050 except ET.ParseError:\r
1051 return sys.exc_value\r
1052\r
1053def namespace():\r
1054 """\r
1055 Test namespace issues.\r
1056\r
1057 1) xml namespace\r
1058\r
1059 >>> elem = ET.XML("<tag xml:lang='en' />")\r
1060 >>> serialize(elem) # 1.1\r
1061 '<tag xml:lang="en" />'\r
1062\r
1063 2) other "well-known" namespaces\r
1064\r
1065 >>> elem = ET.XML("<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' />")\r
1066 >>> serialize(elem) # 2.1\r
1067 '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" />'\r
1068\r
1069 >>> elem = ET.XML("<html:html xmlns:html='http://www.w3.org/1999/xhtml' />")\r
1070 >>> serialize(elem) # 2.2\r
1071 '<html:html xmlns:html="http://www.w3.org/1999/xhtml" />'\r
1072\r
1073 >>> elem = ET.XML("<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope' />")\r
1074 >>> serialize(elem) # 2.3\r
1075 '<ns0:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope" />'\r
1076\r
1077 3) unknown namespaces\r
1078 >>> elem = ET.XML(SAMPLE_XML_NS)\r
1079 >>> print serialize(elem)\r
1080 <ns0:body xmlns:ns0="http://effbot.org/ns">\r
1081 <ns0:tag>text</ns0:tag>\r
1082 <ns0:tag />\r
1083 <ns0:section>\r
1084 <ns0:tag>subtext</ns0:tag>\r
1085 </ns0:section>\r
1086 </ns0:body>\r
1087 """\r
1088\r
1089def qname():\r
1090 """\r
1091 Test QName handling.\r
1092\r
1093 1) decorated tags\r
1094\r
1095 >>> elem = ET.Element("{uri}tag")\r
1096 >>> serialize(elem) # 1.1\r
1097 '<ns0:tag xmlns:ns0="uri" />'\r
1098 >>> elem = ET.Element(ET.QName("{uri}tag"))\r
1099 >>> serialize(elem) # 1.2\r
1100 '<ns0:tag xmlns:ns0="uri" />'\r
1101 >>> elem = ET.Element(ET.QName("uri", "tag"))\r
1102 >>> serialize(elem) # 1.3\r
1103 '<ns0:tag xmlns:ns0="uri" />'\r
1104 >>> elem = ET.Element(ET.QName("uri", "tag"))\r
1105 >>> subelem = ET.SubElement(elem, ET.QName("uri", "tag1"))\r
1106 >>> subelem = ET.SubElement(elem, ET.QName("uri", "tag2"))\r
1107 >>> serialize(elem) # 1.4\r
1108 '<ns0:tag xmlns:ns0="uri"><ns0:tag1 /><ns0:tag2 /></ns0:tag>'\r
1109\r
1110 2) decorated attributes\r
1111\r
1112 >>> elem.clear()\r
1113 >>> elem.attrib["{uri}key"] = "value"\r
1114 >>> serialize(elem) # 2.1\r
1115 '<ns0:tag xmlns:ns0="uri" ns0:key="value" />'\r
1116\r
1117 >>> elem.clear()\r
1118 >>> elem.attrib[ET.QName("{uri}key")] = "value"\r
1119 >>> serialize(elem) # 2.2\r
1120 '<ns0:tag xmlns:ns0="uri" ns0:key="value" />'\r
1121\r
1122 3) decorated values are not converted by default, but the\r
1123 QName wrapper can be used for values\r
1124\r
1125 >>> elem.clear()\r
1126 >>> elem.attrib["{uri}key"] = "{uri}value"\r
1127 >>> serialize(elem) # 3.1\r
1128 '<ns0:tag xmlns:ns0="uri" ns0:key="{uri}value" />'\r
1129\r
1130 >>> elem.clear()\r
1131 >>> elem.attrib["{uri}key"] = ET.QName("{uri}value")\r
1132 >>> serialize(elem) # 3.2\r
1133 '<ns0:tag xmlns:ns0="uri" ns0:key="ns0:value" />'\r
1134\r
1135 >>> elem.clear()\r
1136 >>> subelem = ET.Element("tag")\r
1137 >>> subelem.attrib["{uri1}key"] = ET.QName("{uri2}value")\r
1138 >>> elem.append(subelem)\r
1139 >>> elem.append(subelem)\r
1140 >>> serialize(elem) # 3.3\r
1141 '<ns0:tag xmlns:ns0="uri" xmlns:ns1="uri1" xmlns:ns2="uri2"><tag ns1:key="ns2:value" /><tag ns1:key="ns2:value" /></ns0:tag>'\r
1142\r
1143 4) Direct QName tests\r
1144\r
1145 >>> str(ET.QName('ns', 'tag'))\r
1146 '{ns}tag'\r
1147 >>> str(ET.QName('{ns}tag'))\r
1148 '{ns}tag'\r
1149 >>> q1 = ET.QName('ns', 'tag')\r
1150 >>> q2 = ET.QName('ns', 'tag')\r
1151 >>> q1 == q2\r
1152 True\r
1153 >>> q2 = ET.QName('ns', 'other-tag')\r
1154 >>> q1 == q2\r
1155 False\r
1156 >>> q1 == 'ns:tag'\r
1157 False\r
1158 >>> q1 == '{ns}tag'\r
1159 True\r
1160 """\r
1161\r
1162def doctype_public():\r
1163 """\r
1164 Test PUBLIC doctype.\r
1165\r
1166 >>> elem = ET.XML('<!DOCTYPE html PUBLIC'\r
1167 ... ' "-//W3C//DTD XHTML 1.0 Transitional//EN"'\r
1168 ... ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'\r
1169 ... '<html>text</html>')\r
1170\r
1171 """\r
1172\r
1173def xpath_tokenizer(p):\r
1174 """\r
1175 Test the XPath tokenizer.\r
1176\r
1177 >>> # tests from the xml specification\r
1178 >>> xpath_tokenizer("*")\r
1179 ['*']\r
1180 >>> xpath_tokenizer("text()")\r
1181 ['text', '()']\r
1182 >>> xpath_tokenizer("@name")\r
1183 ['@', 'name']\r
1184 >>> xpath_tokenizer("@*")\r
1185 ['@', '*']\r
1186 >>> xpath_tokenizer("para[1]")\r
1187 ['para', '[', '1', ']']\r
1188 >>> xpath_tokenizer("para[last()]")\r
1189 ['para', '[', 'last', '()', ']']\r
1190 >>> xpath_tokenizer("*/para")\r
1191 ['*', '/', 'para']\r
1192 >>> xpath_tokenizer("/doc/chapter[5]/section[2]")\r
1193 ['/', 'doc', '/', 'chapter', '[', '5', ']', '/', 'section', '[', '2', ']']\r
1194 >>> xpath_tokenizer("chapter//para")\r
1195 ['chapter', '//', 'para']\r
1196 >>> xpath_tokenizer("//para")\r
1197 ['//', 'para']\r
1198 >>> xpath_tokenizer("//olist/item")\r
1199 ['//', 'olist', '/', 'item']\r
1200 >>> xpath_tokenizer(".")\r
1201 ['.']\r
1202 >>> xpath_tokenizer(".//para")\r
1203 ['.', '//', 'para']\r
1204 >>> xpath_tokenizer("..")\r
1205 ['..']\r
1206 >>> xpath_tokenizer("../@lang")\r
1207 ['..', '/', '@', 'lang']\r
1208 >>> xpath_tokenizer("chapter[title]")\r
1209 ['chapter', '[', 'title', ']']\r
1210 >>> xpath_tokenizer("employee[@secretary and @assistant]")\r
1211 ['employee', '[', '@', 'secretary', '', 'and', '', '@', 'assistant', ']']\r
1212\r
1213 >>> # additional tests\r
1214 >>> xpath_tokenizer("{http://spam}egg")\r
1215 ['{http://spam}egg']\r
1216 >>> xpath_tokenizer("./spam.egg")\r
1217 ['.', '/', 'spam.egg']\r
1218 >>> xpath_tokenizer(".//{http://spam}egg")\r
1219 ['.', '//', '{http://spam}egg']\r
1220 """\r
1221 from xml.etree import ElementPath\r
1222 out = []\r
1223 for op, tag in ElementPath.xpath_tokenizer(p):\r
1224 out.append(op or tag)\r
1225 return out\r
1226\r
1227def processinginstruction():\r
1228 """\r
1229 Test ProcessingInstruction directly\r
1230\r
1231 >>> ET.tostring(ET.ProcessingInstruction('test', 'instruction'))\r
1232 '<?test instruction?>'\r
1233 >>> ET.tostring(ET.PI('test', 'instruction'))\r
1234 '<?test instruction?>'\r
1235\r
1236 Issue #2746\r
1237\r
1238 >>> ET.tostring(ET.PI('test', '<testing&>'))\r
1239 '<?test <testing&>?>'\r
1240 >>> ET.tostring(ET.PI('test', u'<testing&>\xe3'), 'latin1')\r
1241 "<?xml version='1.0' encoding='latin1'?>\\n<?test <testing&>\\xe3?>"\r
1242 """\r
1243\r
1244#\r
1245# xinclude tests (samples from appendix C of the xinclude specification)\r
1246\r
1247XINCLUDE = {}\r
1248\r
1249XINCLUDE["C1.xml"] = """\\r
1250<?xml version='1.0'?>\r
1251<document xmlns:xi="http://www.w3.org/2001/XInclude">\r
1252 <p>120 Mz is adequate for an average home user.</p>\r
1253 <xi:include href="disclaimer.xml"/>\r
1254</document>\r
1255"""\r
1256\r
1257XINCLUDE["disclaimer.xml"] = """\\r
1258<?xml version='1.0'?>\r
1259<disclaimer>\r
1260 <p>The opinions represented herein represent those of the individual\r
1261 and should not be interpreted as official policy endorsed by this\r
1262 organization.</p>\r
1263</disclaimer>\r
1264"""\r
1265\r
1266XINCLUDE["C2.xml"] = """\\r
1267<?xml version='1.0'?>\r
1268<document xmlns:xi="http://www.w3.org/2001/XInclude">\r
1269 <p>This document has been accessed\r
1270 <xi:include href="count.txt" parse="text"/> times.</p>\r
1271</document>\r
1272"""\r
1273\r
1274XINCLUDE["count.txt"] = "324387"\r
1275\r
1276XINCLUDE["C2b.xml"] = """\\r
1277<?xml version='1.0'?>\r
1278<document xmlns:xi="http://www.w3.org/2001/XInclude">\r
1279 <p>This document has been <em>accessed</em>\r
1280 <xi:include href="count.txt" parse="text"/> times.</p>\r
1281</document>\r
1282"""\r
1283\r
1284XINCLUDE["C3.xml"] = """\\r
1285<?xml version='1.0'?>\r
1286<document xmlns:xi="http://www.w3.org/2001/XInclude">\r
1287 <p>The following is the source of the "data.xml" resource:</p>\r
1288 <example><xi:include href="data.xml" parse="text"/></example>\r
1289</document>\r
1290"""\r
1291\r
1292XINCLUDE["data.xml"] = """\\r
1293<?xml version='1.0'?>\r
1294<data>\r
1295 <item><![CDATA[Brooks & Shields]]></item>\r
1296</data>\r
1297"""\r
1298\r
1299XINCLUDE["C5.xml"] = """\\r
1300<?xml version='1.0'?>\r
1301<div xmlns:xi="http://www.w3.org/2001/XInclude">\r
1302 <xi:include href="example.txt" parse="text">\r
1303 <xi:fallback>\r
1304 <xi:include href="fallback-example.txt" parse="text">\r
1305 <xi:fallback><a href="mailto:bob@example.org">Report error</a></xi:fallback>\r
1306 </xi:include>\r
1307 </xi:fallback>\r
1308 </xi:include>\r
1309</div>\r
1310"""\r
1311\r
1312XINCLUDE["default.xml"] = """\\r
1313<?xml version='1.0'?>\r
1314<document xmlns:xi="http://www.w3.org/2001/XInclude">\r
1315 <p>Example.</p>\r
1316 <xi:include href="{}"/>\r
1317</document>\r
1318""".format(cgi.escape(SIMPLE_XMLFILE, True))\r
1319\r
1320def xinclude_loader(href, parse="xml", encoding=None):\r
1321 try:\r
1322 data = XINCLUDE[href]\r
1323 except KeyError:\r
1324 raise IOError("resource not found")\r
1325 if parse == "xml":\r
1326 from xml.etree.ElementTree import XML\r
1327 return XML(data)\r
1328 return data\r
1329\r
1330def xinclude():\r
1331 r"""\r
1332 Basic inclusion example (XInclude C.1)\r
1333\r
1334 >>> from xml.etree import ElementTree as ET\r
1335 >>> from xml.etree import ElementInclude\r
1336\r
1337 >>> document = xinclude_loader("C1.xml")\r
1338 >>> ElementInclude.include(document, xinclude_loader)\r
1339 >>> print serialize(document) # C1\r
1340 <document>\r
1341 <p>120 Mz is adequate for an average home user.</p>\r
1342 <disclaimer>\r
1343 <p>The opinions represented herein represent those of the individual\r
1344 and should not be interpreted as official policy endorsed by this\r
1345 organization.</p>\r
1346 </disclaimer>\r
1347 </document>\r
1348\r
1349 Textual inclusion example (XInclude C.2)\r
1350\r
1351 >>> document = xinclude_loader("C2.xml")\r
1352 >>> ElementInclude.include(document, xinclude_loader)\r
1353 >>> print serialize(document) # C2\r
1354 <document>\r
1355 <p>This document has been accessed\r
1356 324387 times.</p>\r
1357 </document>\r
1358\r
1359 Textual inclusion after sibling element (based on modified XInclude C.2)\r
1360\r
1361 >>> document = xinclude_loader("C2b.xml")\r
1362 >>> ElementInclude.include(document, xinclude_loader)\r
1363 >>> print(serialize(document)) # C2b\r
1364 <document>\r
1365 <p>This document has been <em>accessed</em>\r
1366 324387 times.</p>\r
1367 </document>\r
1368\r
1369 Textual inclusion of XML example (XInclude C.3)\r
1370\r
1371 >>> document = xinclude_loader("C3.xml")\r
1372 >>> ElementInclude.include(document, xinclude_loader)\r
1373 >>> print serialize(document) # C3\r
1374 <document>\r
1375 <p>The following is the source of the "data.xml" resource:</p>\r
1376 <example>&lt;?xml version='1.0'?&gt;\r
1377 &lt;data&gt;\r
1378 &lt;item&gt;&lt;![CDATA[Brooks &amp; Shields]]&gt;&lt;/item&gt;\r
1379 &lt;/data&gt;\r
1380 </example>\r
1381 </document>\r
1382\r
1383 Fallback example (XInclude C.5)\r
1384 Note! Fallback support is not yet implemented\r
1385\r
1386 >>> document = xinclude_loader("C5.xml")\r
1387 >>> ElementInclude.include(document, xinclude_loader)\r
1388 Traceback (most recent call last):\r
1389 IOError: resource not found\r
1390 >>> # print serialize(document) # C5\r
1391 """\r
1392\r
1393def xinclude_default():\r
1394 """\r
1395 >>> from xml.etree import ElementInclude\r
1396\r
1397 >>> document = xinclude_loader("default.xml")\r
1398 >>> ElementInclude.include(document)\r
1399 >>> print serialize(document) # default\r
1400 <document>\r
1401 <p>Example.</p>\r
1402 <root>\r
1403 <element key="value">text</element>\r
1404 <element>text</element>tail\r
1405 <empty-element />\r
1406 </root>\r
1407 </document>\r
1408 """\r
1409\r
1410#\r
1411# badly formatted xi:include tags\r
1412\r
1413XINCLUDE_BAD = {}\r
1414\r
1415XINCLUDE_BAD["B1.xml"] = """\\r
1416<?xml version='1.0'?>\r
1417<document xmlns:xi="http://www.w3.org/2001/XInclude">\r
1418 <p>120 Mz is adequate for an average home user.</p>\r
1419 <xi:include href="disclaimer.xml" parse="BAD_TYPE"/>\r
1420</document>\r
1421"""\r
1422\r
1423XINCLUDE_BAD["B2.xml"] = """\\r
1424<?xml version='1.0'?>\r
1425<div xmlns:xi="http://www.w3.org/2001/XInclude">\r
1426 <xi:fallback></xi:fallback>\r
1427</div>\r
1428"""\r
1429\r
1430def xinclude_failures():\r
1431 r"""\r
1432 Test failure to locate included XML file.\r
1433\r
1434 >>> from xml.etree import ElementInclude\r
1435\r
1436 >>> def none_loader(href, parser, encoding=None):\r
1437 ... return None\r
1438\r
1439 >>> document = ET.XML(XINCLUDE["C1.xml"])\r
1440 >>> ElementInclude.include(document, loader=none_loader)\r
1441 Traceback (most recent call last):\r
1442 FatalIncludeError: cannot load 'disclaimer.xml' as 'xml'\r
1443\r
1444 Test failure to locate included text file.\r
1445\r
1446 >>> document = ET.XML(XINCLUDE["C2.xml"])\r
1447 >>> ElementInclude.include(document, loader=none_loader)\r
1448 Traceback (most recent call last):\r
1449 FatalIncludeError: cannot load 'count.txt' as 'text'\r
1450\r
1451 Test bad parse type.\r
1452\r
1453 >>> document = ET.XML(XINCLUDE_BAD["B1.xml"])\r
1454 >>> ElementInclude.include(document, loader=none_loader)\r
1455 Traceback (most recent call last):\r
1456 FatalIncludeError: unknown parse type in xi:include tag ('BAD_TYPE')\r
1457\r
1458 Test xi:fallback outside xi:include.\r
1459\r
1460 >>> document = ET.XML(XINCLUDE_BAD["B2.xml"])\r
1461 >>> ElementInclude.include(document, loader=none_loader)\r
1462 Traceback (most recent call last):\r
1463 FatalIncludeError: xi:fallback tag must be child of xi:include ('{http://www.w3.org/2001/XInclude}fallback')\r
1464 """\r
1465\r
1466# --------------------------------------------------------------------\r
1467# reported bugs\r
1468\r
1469def bug_xmltoolkit21():\r
1470 """\r
1471\r
1472 marshaller gives obscure errors for non-string values\r
1473\r
1474 >>> elem = ET.Element(123)\r
1475 >>> serialize(elem) # tag\r
1476 Traceback (most recent call last):\r
1477 TypeError: cannot serialize 123 (type int)\r
1478 >>> elem = ET.Element("elem")\r
1479 >>> elem.text = 123\r
1480 >>> serialize(elem) # text\r
1481 Traceback (most recent call last):\r
1482 TypeError: cannot serialize 123 (type int)\r
1483 >>> elem = ET.Element("elem")\r
1484 >>> elem.tail = 123\r
1485 >>> serialize(elem) # tail\r
1486 Traceback (most recent call last):\r
1487 TypeError: cannot serialize 123 (type int)\r
1488 >>> elem = ET.Element("elem")\r
1489 >>> elem.set(123, "123")\r
1490 >>> serialize(elem) # attribute key\r
1491 Traceback (most recent call last):\r
1492 TypeError: cannot serialize 123 (type int)\r
1493 >>> elem = ET.Element("elem")\r
1494 >>> elem.set("123", 123)\r
1495 >>> serialize(elem) # attribute value\r
1496 Traceback (most recent call last):\r
1497 TypeError: cannot serialize 123 (type int)\r
1498\r
1499 """\r
1500\r
1501def bug_xmltoolkit25():\r
1502 """\r
1503\r
1504 typo in ElementTree.findtext\r
1505\r
1506 >>> elem = ET.XML(SAMPLE_XML)\r
1507 >>> tree = ET.ElementTree(elem)\r
1508 >>> tree.findtext("tag")\r
1509 'text'\r
1510 >>> tree.findtext("section/tag")\r
1511 'subtext'\r
1512\r
1513 """\r
1514\r
1515def bug_xmltoolkit28():\r
1516 """\r
1517\r
1518 .//tag causes exceptions\r
1519\r
1520 >>> tree = ET.XML("<doc><table><tbody/></table></doc>")\r
1521 >>> summarize_list(tree.findall(".//thead"))\r
1522 []\r
1523 >>> summarize_list(tree.findall(".//tbody"))\r
1524 ['tbody']\r
1525\r
1526 """\r
1527\r
1528def bug_xmltoolkitX1():\r
1529 """\r
1530\r
1531 dump() doesn't flush the output buffer\r
1532\r
1533 >>> tree = ET.XML("<doc><table><tbody/></table></doc>")\r
1534 >>> ET.dump(tree); sys.stdout.write("tail")\r
1535 <doc><table><tbody /></table></doc>\r
1536 tail\r
1537\r
1538 """\r
1539\r
1540def bug_xmltoolkit39():\r
1541 """\r
1542\r
1543 non-ascii element and attribute names doesn't work\r
1544\r
1545 >>> tree = ET.XML("<?xml version='1.0' encoding='iso-8859-1'?><t\xe4g />")\r
1546 >>> ET.tostring(tree, "utf-8")\r
1547 '<t\\xc3\\xa4g />'\r
1548\r
1549 >>> tree = ET.XML("<?xml version='1.0' encoding='iso-8859-1'?><tag \xe4ttr='v&#228;lue' />")\r
1550 >>> tree.attrib\r
1551 {u'\\xe4ttr': u'v\\xe4lue'}\r
1552 >>> ET.tostring(tree, "utf-8")\r
1553 '<tag \\xc3\\xa4ttr="v\\xc3\\xa4lue" />'\r
1554\r
1555 >>> tree = ET.XML("<?xml version='1.0' encoding='iso-8859-1'?><t\xe4g>text</t\xe4g>")\r
1556 >>> ET.tostring(tree, "utf-8")\r
1557 '<t\\xc3\\xa4g>text</t\\xc3\\xa4g>'\r
1558\r
1559 >>> tree = ET.Element(u"t\u00e4g")\r
1560 >>> ET.tostring(tree, "utf-8")\r
1561 '<t\\xc3\\xa4g />'\r
1562\r
1563 >>> tree = ET.Element("tag")\r
1564 >>> tree.set(u"\u00e4ttr", u"v\u00e4lue")\r
1565 >>> ET.tostring(tree, "utf-8")\r
1566 '<tag \\xc3\\xa4ttr="v\\xc3\\xa4lue" />'\r
1567\r
1568 """\r
1569\r
1570def bug_xmltoolkit54():\r
1571 """\r
1572\r
1573 problems handling internally defined entities\r
1574\r
1575 >>> e = ET.XML("<!DOCTYPE doc [<!ENTITY ldots '&#x8230;'>]><doc>&ldots;</doc>")\r
1576 >>> serialize(e)\r
1577 '<doc>&#33328;</doc>'\r
1578\r
1579 """\r
1580\r
1581def bug_xmltoolkit55():\r
1582 """\r
1583\r
1584 make sure we're reporting the first error, not the last\r
1585\r
1586 >>> e = ET.XML("<!DOCTYPE doc SYSTEM 'doc.dtd'><doc>&ldots;&ndots;&rdots;</doc>")\r
1587 Traceback (most recent call last):\r
1588 ParseError: undefined entity &ldots;: line 1, column 36\r
1589\r
1590 """\r
1591\r
1592class ExceptionFile:\r
1593 def read(self, x):\r
1594 raise IOError\r
1595\r
1596def xmltoolkit60():\r
1597 """\r
1598\r
1599 Handle crash in stream source.\r
1600 >>> tree = ET.parse(ExceptionFile())\r
1601 Traceback (most recent call last):\r
1602 IOError\r
1603\r
1604 """\r
1605\r
1606XMLTOOLKIT62_DOC = """<?xml version="1.0" encoding="UTF-8"?>\r
1607<!DOCTYPE patent-application-publication SYSTEM "pap-v15-2001-01-31.dtd" []>\r
1608<patent-application-publication>\r
1609<subdoc-abstract>\r
1610<paragraph id="A-0001" lvl="0">A new cultivar of Begonia plant named &lsquo;BCT9801BEG&rsquo;.</paragraph>\r
1611</subdoc-abstract>\r
1612</patent-application-publication>"""\r
1613\r
1614\r
1615def xmltoolkit62():\r
1616 """\r
1617\r
1618 Don't crash when using custom entities.\r
1619\r
1620 >>> xmltoolkit62()\r
1621 u'A new cultivar of Begonia plant named \u2018BCT9801BEG\u2019.'\r
1622\r
1623 """\r
1624 ENTITIES = {u'rsquo': u'\u2019', u'lsquo': u'\u2018'}\r
1625 parser = ET.XMLTreeBuilder()\r
1626 parser.entity.update(ENTITIES)\r
1627 parser.feed(XMLTOOLKIT62_DOC)\r
1628 t = parser.close()\r
1629 return t.find('.//paragraph').text\r
1630\r
1631def xmltoolkit63():\r
1632 """\r
1633\r
1634 Check reference leak.\r
1635 >>> xmltoolkit63()\r
1636 >>> count = sys.getrefcount(None)\r
1637 >>> for i in range(1000):\r
1638 ... xmltoolkit63()\r
1639 >>> sys.getrefcount(None) - count\r
1640 0\r
1641\r
1642 """\r
1643 tree = ET.TreeBuilder()\r
1644 tree.start("tag", {})\r
1645 tree.data("text")\r
1646 tree.end("tag")\r
1647\r
1648# --------------------------------------------------------------------\r
1649\r
1650\r
1651def bug_200708_newline():\r
1652 r"""\r
1653\r
1654 Preserve newlines in attributes.\r
1655\r
1656 >>> e = ET.Element('SomeTag', text="def _f():\n return 3\n")\r
1657 >>> ET.tostring(e)\r
1658 '<SomeTag text="def _f():&#10; return 3&#10;" />'\r
1659 >>> ET.XML(ET.tostring(e)).get("text")\r
1660 'def _f():\n return 3\n'\r
1661 >>> ET.tostring(ET.XML(ET.tostring(e)))\r
1662 '<SomeTag text="def _f():&#10; return 3&#10;" />'\r
1663\r
1664 """\r
1665\r
1666def bug_200708_close():\r
1667 """\r
1668\r
1669 Test default builder.\r
1670 >>> parser = ET.XMLParser() # default\r
1671 >>> parser.feed("<element>some text</element>")\r
1672 >>> summarize(parser.close())\r
1673 'element'\r
1674\r
1675 Test custom builder.\r
1676 >>> class EchoTarget:\r
1677 ... def close(self):\r
1678 ... return ET.Element("element") # simulate root\r
1679 >>> parser = ET.XMLParser(EchoTarget())\r
1680 >>> parser.feed("<element>some text</element>")\r
1681 >>> summarize(parser.close())\r
1682 'element'\r
1683\r
1684 """\r
1685\r
1686def bug_200709_default_namespace():\r
1687 """\r
1688\r
1689 >>> e = ET.Element("{default}elem")\r
1690 >>> s = ET.SubElement(e, "{default}elem")\r
1691 >>> serialize(e, default_namespace="default") # 1\r
1692 '<elem xmlns="default"><elem /></elem>'\r
1693\r
1694 >>> e = ET.Element("{default}elem")\r
1695 >>> s = ET.SubElement(e, "{default}elem")\r
1696 >>> s = ET.SubElement(e, "{not-default}elem")\r
1697 >>> serialize(e, default_namespace="default") # 2\r
1698 '<elem xmlns="default" xmlns:ns1="not-default"><elem /><ns1:elem /></elem>'\r
1699\r
1700 >>> e = ET.Element("{default}elem")\r
1701 >>> s = ET.SubElement(e, "{default}elem")\r
1702 >>> s = ET.SubElement(e, "elem") # unprefixed name\r
1703 >>> serialize(e, default_namespace="default") # 3\r
1704 Traceback (most recent call last):\r
1705 ValueError: cannot use non-qualified names with default_namespace option\r
1706\r
1707 """\r
1708\r
1709def bug_200709_register_namespace():\r
1710 """\r
1711\r
1712 >>> ET.tostring(ET.Element("{http://namespace.invalid/does/not/exist/}title"))\r
1713 '<ns0:title xmlns:ns0="http://namespace.invalid/does/not/exist/" />'\r
1714 >>> ET.register_namespace("foo", "http://namespace.invalid/does/not/exist/")\r
1715 >>> ET.tostring(ET.Element("{http://namespace.invalid/does/not/exist/}title"))\r
1716 '<foo:title xmlns:foo="http://namespace.invalid/does/not/exist/" />'\r
1717\r
1718 And the Dublin Core namespace is in the default list:\r
1719\r
1720 >>> ET.tostring(ET.Element("{http://purl.org/dc/elements/1.1/}title"))\r
1721 '<dc:title xmlns:dc="http://purl.org/dc/elements/1.1/" />'\r
1722\r
1723 """\r
1724\r
1725def bug_200709_element_comment():\r
1726 """\r
1727\r
1728 Not sure if this can be fixed, really (since the serializer needs\r
1729 ET.Comment, not cET.comment).\r
1730\r
1731 >>> a = ET.Element('a')\r
1732 >>> a.append(ET.Comment('foo'))\r
1733 >>> a[0].tag == ET.Comment\r
1734 True\r
1735\r
1736 >>> a = ET.Element('a')\r
1737 >>> a.append(ET.PI('foo'))\r
1738 >>> a[0].tag == ET.PI\r
1739 True\r
1740\r
1741 """\r
1742\r
1743def bug_200709_element_insert():\r
1744 """\r
1745\r
1746 >>> a = ET.Element('a')\r
1747 >>> b = ET.SubElement(a, 'b')\r
1748 >>> c = ET.SubElement(a, 'c')\r
1749 >>> d = ET.Element('d')\r
1750 >>> a.insert(0, d)\r
1751 >>> summarize_list(a)\r
1752 ['d', 'b', 'c']\r
1753 >>> a.insert(-1, d)\r
1754 >>> summarize_list(a)\r
1755 ['d', 'b', 'd', 'c']\r
1756\r
1757 """\r
1758\r
1759def bug_200709_iter_comment():\r
1760 """\r
1761\r
1762 >>> a = ET.Element('a')\r
1763 >>> b = ET.SubElement(a, 'b')\r
1764 >>> comment_b = ET.Comment("TEST-b")\r
1765 >>> b.append(comment_b)\r
1766 >>> summarize_list(a.iter(ET.Comment))\r
1767 ['<Comment>']\r
1768\r
1769 """\r
1770\r
1771# --------------------------------------------------------------------\r
1772# reported on bugs.python.org\r
1773\r
1774def bug_1534630():\r
1775 """\r
1776\r
1777 >>> bob = ET.TreeBuilder()\r
1778 >>> e = bob.data("data")\r
1779 >>> e = bob.start("tag", {})\r
1780 >>> e = bob.end("tag")\r
1781 >>> e = bob.close()\r
1782 >>> serialize(e)\r
1783 '<tag />'\r
1784\r
1785 """\r
1786\r
1787def check_issue6233():\r
1788 """\r
1789\r
1790 >>> e = ET.XML("<?xml version='1.0' encoding='utf-8'?><body>t\\xc3\\xa3g</body>")\r
1791 >>> ET.tostring(e, 'ascii')\r
1792 "<?xml version='1.0' encoding='ascii'?>\\n<body>t&#227;g</body>"\r
1793 >>> e = ET.XML("<?xml version='1.0' encoding='iso-8859-1'?><body>t\\xe3g</body>")\r
1794 >>> ET.tostring(e, 'ascii')\r
1795 "<?xml version='1.0' encoding='ascii'?>\\n<body>t&#227;g</body>"\r
1796\r
1797 """\r
1798\r
1799def check_issue3151():\r
1800 """\r
1801\r
1802 >>> e = ET.XML('<prefix:localname xmlns:prefix="${stuff}"/>')\r
1803 >>> e.tag\r
1804 '{${stuff}}localname'\r
1805 >>> t = ET.ElementTree(e)\r
1806 >>> ET.tostring(e)\r
1807 '<ns0:localname xmlns:ns0="${stuff}" />'\r
1808\r
1809 """\r
1810\r
1811def check_issue6565():\r
1812 """\r
1813\r
1814 >>> elem = ET.XML("<body><tag/></body>")\r
1815 >>> summarize_list(elem)\r
1816 ['tag']\r
1817 >>> newelem = ET.XML(SAMPLE_XML)\r
1818 >>> elem[:] = newelem[:]\r
1819 >>> summarize_list(elem)\r
1820 ['tag', 'tag', 'section']\r
1821\r
1822 """\r
1823\r
1824# --------------------------------------------------------------------\r
1825\r
1826\r
1827class CleanContext(object):\r
1828 """Provide default namespace mapping and path cache."""\r
1829 checkwarnings = None\r
1830\r
1831 def __init__(self, quiet=False):\r
1832 if sys.flags.optimize >= 2:\r
1833 # under -OO, doctests cannot be run and therefore not all warnings\r
1834 # will be emitted\r
1835 quiet = True\r
1836 deprecations = (\r
1837 # Search behaviour is broken if search path starts with "/".\r
1838 ("This search is broken in 1.3 and earlier, and will be fixed "\r
1839 "in a future version. If you rely on the current behaviour, "\r
1840 "change it to '.+'", FutureWarning),\r
1841 # Element.getchildren() and Element.getiterator() are deprecated.\r
1842 ("This method will be removed in future versions. "\r
1843 "Use .+ instead.", DeprecationWarning),\r
1844 ("This method will be removed in future versions. "\r
1845 "Use .+ instead.", PendingDeprecationWarning),\r
1846 # XMLParser.doctype() is deprecated.\r
1847 ("This method of XMLParser is deprecated. Define doctype.. "\r
1848 "method on the TreeBuilder target.", DeprecationWarning))\r
1849 self.checkwarnings = test_support.check_warnings(*deprecations,\r
1850 quiet=quiet)\r
1851\r
1852 def __enter__(self):\r
1853 from xml.etree import ElementTree\r
1854 self._nsmap = ElementTree._namespace_map\r
1855 self._path_cache = ElementTree.ElementPath._cache\r
1856 # Copy the default namespace mapping\r
1857 ElementTree._namespace_map = self._nsmap.copy()\r
1858 # Copy the path cache (should be empty)\r
1859 ElementTree.ElementPath._cache = self._path_cache.copy()\r
1860 self.checkwarnings.__enter__()\r
1861\r
1862 def __exit__(self, *args):\r
1863 from xml.etree import ElementTree\r
1864 # Restore mapping and path cache\r
1865 ElementTree._namespace_map = self._nsmap\r
1866 ElementTree.ElementPath._cache = self._path_cache\r
1867 self.checkwarnings.__exit__(*args)\r
1868\r
1869\r
1870def test_main(module_name='xml.etree.ElementTree'):\r
1871 from test import test_xml_etree\r
1872\r
1873 use_py_module = (module_name == 'xml.etree.ElementTree')\r
1874\r
1875 # The same doctests are used for both the Python and the C implementations\r
1876 assert test_xml_etree.ET.__name__ == module_name\r
1877\r
1878 # XXX the C module should give the same warnings as the Python module\r
1879 with CleanContext(quiet=not use_py_module):\r
1880 test_support.run_doctest(test_xml_etree, verbosity=True)\r
1881\r
1882 # The module should not be changed by the tests\r
1883 assert test_xml_etree.ET.__name__ == module_name\r
1884\r
1885if __name__ == '__main__':\r
1886 test_main()\r