Package lxml :: Package tests :: Module test_etree
[hide private]
[frames] | no frames]

Source Code for Module lxml.tests.test_etree

   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  from __future__ import absolute_import 
  11   
  12  import os.path 
  13  import unittest 
  14  import copy 
  15  import sys 
  16  import re 
  17  import gc 
  18  import operator 
  19  import tempfile 
  20  import textwrap 
  21  import zlib 
  22  import gzip 
  23   
  24  from .common_imports import etree, StringIO, BytesIO, HelperTestCase 
  25  from .common_imports import fileInTestDir, fileUrlInTestDir, read_file, path2url, tmpfile 
  26  from .common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest 
  27  from .common_imports import canonicalize, _str, _bytes 
  28   
  29  print(""" 
  30  TESTED VERSION: %s""" % etree.__version__ + """ 
  31      Python:           %r""" % (sys.version_info,) + """ 
  32      lxml.etree:       %r""" % (etree.LXML_VERSION,) + """ 
  33      libxml used:      %r""" % (etree.LIBXML_VERSION,) + """ 
  34      libxml compiled:  %r""" % (etree.LIBXML_COMPILED_VERSION,) + """ 
  35      libxslt used:     %r""" % (etree.LIBXSLT_VERSION,) + """ 
  36      libxslt compiled: %r""" % (etree.LIBXSLT_COMPILED_VERSION,) + """ 
  37      FS encoding:      %s""" % (sys.getfilesystemencoding(),) + """ 
  38      Default encoding: %s""" % (sys.getdefaultencoding(),) + """ 
  39      Max Unicode:      %s""" % (sys.maxunicode,) + """ 
  40  """) 
  41   
  42  try: 
  43      _unicode = unicode 
  44  except NameError: 
  45      # Python 3 
  46      _unicode = str 
  47   
  48   
49 -class ETreeOnlyTestCase(HelperTestCase):
50 """Tests only for etree, not ElementTree""" 51 etree = etree 52
53 - def test_version(self):
54 self.assertTrue(isinstance(etree.__version__, _unicode)) 55 self.assertTrue(isinstance(etree.LXML_VERSION, tuple)) 56 self.assertEqual(len(etree.LXML_VERSION), 4) 57 self.assertTrue(isinstance(etree.LXML_VERSION[0], int)) 58 self.assertTrue(isinstance(etree.LXML_VERSION[1], int)) 59 self.assertTrue(isinstance(etree.LXML_VERSION[2], int)) 60 self.assertTrue(isinstance(etree.LXML_VERSION[3], int)) 61 self.assertTrue(etree.__version__.startswith( 62 str(etree.LXML_VERSION[0])))
63
64 - def test_c_api(self):
65 if hasattr(self.etree, '__pyx_capi__'): 66 # newer Pyrex compatible C-API 67 self.assertTrue(isinstance(self.etree.__pyx_capi__, dict)) 68 self.assertTrue(len(self.etree.__pyx_capi__) > 0) 69 else: 70 # older C-API mechanism 71 self.assertTrue(hasattr(self.etree, '_import_c_api'))
72
73 - def test_include_paths(self):
74 import lxml 75 includes = lxml.get_include() 76 self.assertTrue(includes) 77 self.assertTrue(len(includes) >= 2) 78 self.assertTrue(os.path.join(os.path.dirname(lxml.__file__), 'includes') in includes, 79 includes)
80
81 - def test_element_names(self):
82 Element = self.etree.Element 83 el = Element('name') 84 self.assertEqual(el.tag, 'name') 85 el = Element('{}name') 86 self.assertEqual(el.tag, 'name')
87
88 - def test_element_name_empty(self):
89 Element = self.etree.Element 90 el = Element('name') 91 self.assertRaises(ValueError, Element, '{}') 92 self.assertRaises(ValueError, setattr, el, 'tag', '{}') 93 94 self.assertRaises(ValueError, Element, '{test}') 95 self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
96
97 - def test_element_name_colon(self):
98 Element = self.etree.Element 99 self.assertRaises(ValueError, Element, 'p:name') 100 self.assertRaises(ValueError, Element, '{test}p:name') 101 102 el = Element('name') 103 self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
104
105 - def test_element_name_quote(self):
106 Element = self.etree.Element 107 self.assertRaises(ValueError, Element, "p'name") 108 self.assertRaises(ValueError, Element, 'p"name') 109 110 self.assertRaises(ValueError, Element, "{test}p'name") 111 self.assertRaises(ValueError, Element, '{test}p"name') 112 113 el = Element('name') 114 self.assertRaises(ValueError, setattr, el, 'tag', "p'name") 115 self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
116
117 - def test_element_name_space(self):
118 Element = self.etree.Element 119 self.assertRaises(ValueError, Element, ' name ') 120 self.assertRaises(ValueError, Element, 'na me') 121 self.assertRaises(ValueError, Element, '{test} name') 122 123 el = Element('name') 124 self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
125
126 - def test_subelement_name_empty(self):
127 Element = self.etree.Element 128 SubElement = self.etree.SubElement 129 130 el = Element('name') 131 self.assertRaises(ValueError, SubElement, el, '{}') 132 self.assertRaises(ValueError, SubElement, el, '{test}')
133
134 - def test_subelement_name_colon(self):
135 Element = self.etree.Element 136 SubElement = self.etree.SubElement 137 138 el = Element('name') 139 self.assertRaises(ValueError, SubElement, el, 'p:name') 140 self.assertRaises(ValueError, SubElement, el, '{test}p:name')
141
142 - def test_subelement_name_quote(self):
143 Element = self.etree.Element 144 SubElement = self.etree.SubElement 145 146 el = Element('name') 147 self.assertRaises(ValueError, SubElement, el, "p'name") 148 self.assertRaises(ValueError, SubElement, el, "{test}p'name") 149 150 self.assertRaises(ValueError, SubElement, el, 'p"name') 151 self.assertRaises(ValueError, SubElement, el, '{test}p"name')
152
153 - def test_subelement_name_space(self):
154 Element = self.etree.Element 155 SubElement = self.etree.SubElement 156 157 el = Element('name') 158 self.assertRaises(ValueError, SubElement, el, ' name ') 159 self.assertRaises(ValueError, SubElement, el, 'na me') 160 self.assertRaises(ValueError, SubElement, el, '{test} name')
161
163 Element = self.etree.Element 164 SubElement = self.etree.SubElement 165 166 el = Element('name') 167 self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'}) 168 self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'}) 169 self.assertEqual(0, len(el))
170
171 - def test_qname_empty(self):
172 QName = self.etree.QName 173 self.assertRaises(ValueError, QName, '') 174 self.assertRaises(ValueError, QName, None) 175 self.assertRaises(ValueError, QName, None, None) 176 self.assertRaises(ValueError, QName, 'test', '')
177
178 - def test_qname_none(self):
179 QName = self.etree.QName 180 q = QName(None, 'TAG') 181 self.assertEqual('TAG', q) 182 self.assertEqual('TAG', q.localname) 183 self.assertEqual(None, q.namespace)
184
185 - def test_qname_colon(self):
186 QName = self.etree.QName 187 self.assertRaises(ValueError, QName, 'p:name') 188 self.assertRaises(ValueError, QName, 'test', 'p:name')
189
190 - def test_qname_space(self):
191 QName = self.etree.QName 192 self.assertRaises(ValueError, QName, ' name ') 193 self.assertRaises(ValueError, QName, 'na me') 194 self.assertRaises(ValueError, QName, 'test', ' name')
195
197 # ET doesn't have namespace/localname properties on QNames 198 QName = self.etree.QName 199 namespace, localname = 'http://myns', 'a' 200 qname = QName(namespace, localname) 201 self.assertEqual(namespace, qname.namespace) 202 self.assertEqual(localname, qname.localname)
203
204 - def test_qname_element(self):
205 # ET doesn't have namespace/localname properties on QNames 206 QName = self.etree.QName 207 qname1 = QName('http://myns', 'a') 208 a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'}) 209 210 qname2 = QName(a) 211 self.assertEqual(a.tag, qname1.text) 212 self.assertEqual(a.tag, qname1) 213 self.assertEqual(qname1.text, qname2.text) 214 self.assertEqual(qname1, qname2.text) 215 self.assertEqual(qname1.text, qname2) 216 self.assertEqual(qname1, qname2)
217
218 - def test_qname_text_resolve(self):
219 # ET doesn't resove QNames as text values 220 etree = self.etree 221 qname = etree.QName('http://myns', 'a') 222 a = etree.Element(qname, nsmap={'p' : 'http://myns'}) 223 a.text = qname 224 225 self.assertEqual("p:a", a.text)
226
227 - def test_nsmap_prefix_invalid(self):
228 etree = self.etree 229 self.assertRaises(ValueError, 230 etree.Element, "root", nsmap={'"' : 'testns'}) 231 self.assertRaises(ValueError, 232 etree.Element, "root", nsmap={'&' : 'testns'}) 233 self.assertRaises(ValueError, 234 etree.Element, "root", nsmap={'a:b' : 'testns'})
235
236 - def test_clear_keep_tail(self):
237 XML = self.etree.XML 238 tostring = self.etree.tostring 239 a = XML('<a aa="A"><b ba="B">B1</b>B2<c ca="C">C1</c>C2</a>') 240 a[0].clear(keep_tail=True) 241 self.assertEqual(_bytes('<a aa="A"><b/>B2<c ca="C">C1</c>C2</a>'), tostring(a))
242
243 - def test_attribute_has_key(self):
244 # ET in Py 3.x has no "attrib.has_key()" method 245 XML = self.etree.XML 246 247 root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />')) 248 self.assertEqual( 249 True, root.attrib.has_key('bar')) 250 self.assertEqual( 251 False, root.attrib.has_key('baz')) 252 self.assertEqual( 253 False, root.attrib.has_key('hah')) 254 self.assertEqual( 255 True, 256 root.attrib.has_key('{http://ns.codespeak.net/test}baz'))
257
258 - def test_attribute_set(self):
259 Element = self.etree.Element 260 root = Element("root") 261 root.set("attr", "TEST") 262 self.assertEqual("TEST", root.get("attr"))
263
265 # ElementTree accepts arbitrary attribute values 266 # lxml.etree allows only strings 267 Element = self.etree.Element 268 269 root = Element("root") 270 root.set("attr", "TEST") 271 self.assertEqual("TEST", root.get("attr")) 272 self.assertRaises(TypeError, root.set, "newattr", 5)
273
274 - def test_attrib_and_keywords(self):
275 Element = self.etree.Element 276 277 root = Element("root") 278 root.set("attr", "TEST") 279 self.assertEqual("TEST", root.attrib["attr"]) 280 281 root2 = Element("root2", root.attrib, attr2='TOAST') 282 self.assertEqual("TEST", root2.attrib["attr"]) 283 self.assertEqual("TOAST", root2.attrib["attr2"]) 284 self.assertEqual(None, root.attrib.get("attr2"))
285
286 - def test_attrib_order(self):
287 Element = self.etree.Element 288 289 keys = ["attr%d" % i for i in range(10)] 290 values = ["TEST-%d" % i for i in range(10)] 291 items = list(zip(keys, values)) 292 293 root = Element("root") 294 for key, value in items: 295 root.set(key, value) 296 self.assertEqual(keys, root.attrib.keys()) 297 self.assertEqual(values, root.attrib.values()) 298 299 root2 = Element("root2", root.attrib, 300 attr_99='TOAST-1', attr_98='TOAST-2') 301 302 if sys.version_info >= (3, 6): 303 self.assertEqual(['attr_99', 'attr_98'] + keys, 304 root2.attrib.keys()) 305 self.assertEqual(['TOAST-1', 'TOAST-2'] + values, 306 root2.attrib.values()) 307 else: 308 self.assertEqual(['attr_98', 'attr_99'] + keys, 309 root2.attrib.keys()) 310 self.assertEqual(['TOAST-2', 'TOAST-1'] + values, 311 root2.attrib.values()) 312 313 self.assertEqual(keys, root.attrib.keys()) 314 self.assertEqual(values, root.attrib.values())
315
316 - def test_attribute_set_invalid(self):
317 # ElementTree accepts arbitrary attribute values 318 # lxml.etree allows only strings, or None for (html5) boolean attributes 319 Element = self.etree.Element 320 root = Element("root") 321 self.assertRaises(TypeError, root.set, "newattr", 5) 322 self.assertRaises(TypeError, root.set, "newattr", object) 323 self.assertRaises(TypeError, root.set, "newattr", None) 324 self.assertRaises(TypeError, root.set, "newattr")
325
326 - def test_strip_attributes(self):
327 XML = self.etree.XML 328 xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>') 329 330 root = XML(xml) 331 self.etree.strip_attributes(root, 'a') 332 self.assertEqual(_bytes('<test b="10" c="20"><x b="2"></x></test>'), 333 self._writeElement(root)) 334 335 root = XML(xml) 336 self.etree.strip_attributes(root, 'b', 'c') 337 self.assertEqual(_bytes('<test a="5"><x a="4"></x></test>'), 338 self._writeElement(root))
339
340 - def test_strip_attributes_ns(self):
341 XML = self.etree.XML 342 xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>') 343 344 root = XML(xml) 345 self.etree.strip_attributes(root, 'a') 346 self.assertEqual( 347 _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'), 348 self._writeElement(root)) 349 350 root = XML(xml) 351 self.etree.strip_attributes(root, '{http://test/ns}a', 'c') 352 self.assertEqual( 353 _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'), 354 self._writeElement(root)) 355 356 root = XML(xml) 357 self.etree.strip_attributes(root, '{http://test/ns}*') 358 self.assertEqual( 359 _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'), 360 self._writeElement(root))
361
362 - def test_strip_elements(self):
363 XML = self.etree.XML 364 xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>') 365 366 root = XML(xml) 367 self.etree.strip_elements(root, 'a') 368 self.assertEqual(_bytes('<test><x></x></test>'), 369 self._writeElement(root)) 370 371 root = XML(xml) 372 self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z') 373 self.assertEqual(_bytes('<test><a></a><x><a></a></x></test>'), 374 self._writeElement(root)) 375 376 root = XML(xml) 377 self.etree.strip_elements(root, 'c') 378 self.assertEqual(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'), 379 self._writeElement(root))
380
381 - def test_strip_elements_ns(self):
382 XML = self.etree.XML 383 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>') 384 385 root = XML(xml) 386 self.etree.strip_elements(root, 'a') 387 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>'), 388 self._writeElement(root)) 389 390 root = XML(xml) 391 self.etree.strip_elements(root, '{urn:a}b', 'c') 392 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>'), 393 self._writeElement(root)) 394 395 root = XML(xml) 396 self.etree.strip_elements(root, '{urn:a}*', 'c') 397 self.assertEqual(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 398 self._writeElement(root)) 399 400 root = XML(xml) 401 self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False) 402 self.assertEqual(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 403 self._writeElement(root))
404
405 - def test_strip_tags(self):
406 XML = self.etree.XML 407 xml = _bytes('<test>TEST<a>A<b>B<c/>CT</b>BT</a>AT<x>X<a>A<b/>BT<c/>CT</a>AT</x>XT</test>') 408 409 root = XML(xml) 410 self.etree.strip_tags(root, 'a') 411 self.assertEqual(_bytes('<test>TESTA<b>B<c></c>CT</b>BTAT<x>XA<b></b>BT<c></c>CTAT</x>XT</test>'), 412 self._writeElement(root)) 413 414 root = XML(xml) 415 self.etree.strip_tags(root, 'b', 'c', 'X', 'Y', 'Z') 416 self.assertEqual(_bytes('<test>TEST<a>ABCTBT</a>AT<x>X<a>ABTCT</a>AT</x>XT</test>'), 417 self._writeElement(root)) 418 419 root = XML(xml) 420 self.etree.strip_tags(root, 'c') 421 self.assertEqual(_bytes('<test>TEST<a>A<b>BCT</b>BT</a>AT<x>X<a>A<b></b>BTCT</a>AT</x>XT</test>'), 422 self._writeElement(root))
423
424 - def test_strip_tags_pi_comment(self):
425 XML = self.etree.XML 426 PI = self.etree.ProcessingInstruction 427 Comment = self.etree.Comment 428 xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>') 429 430 root = XML(xml) 431 self.etree.strip_tags(root, PI) 432 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->\n<?PI1?>'), 433 self._writeElement(root)) 434 435 root = XML(xml) 436 self.etree.strip_tags(root, Comment) 437 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT<?PI2?></test>\n<!--comment3-->\n<?PI1?>'), 438 self._writeElement(root)) 439 440 root = XML(xml) 441 self.etree.strip_tags(root, PI, Comment) 442 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'), 443 self._writeElement(root)) 444 445 root = XML(xml) 446 self.etree.strip_tags(root, Comment, PI) 447 self.assertEqual(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'), 448 self._writeElement(root))
449
451 XML = self.etree.XML 452 ElementTree = self.etree.ElementTree 453 PI = self.etree.ProcessingInstruction 454 Comment = self.etree.Comment 455 xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>') 456 457 root = XML(xml) 458 self.etree.strip_tags(ElementTree(root), PI) 459 self.assertEqual(_bytes('<!--comment1-->\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->'), 460 self._writeElement(root)) 461 462 root = XML(xml) 463 self.etree.strip_tags(ElementTree(root), Comment) 464 self.assertEqual(_bytes('<?PI1?>\n<test>TESTXT<?PI2?></test>\n<?PI1?>'), 465 self._writeElement(root)) 466 467 root = XML(xml) 468 self.etree.strip_tags(ElementTree(root), PI, Comment) 469 self.assertEqual(_bytes('<test>TESTXT</test>'), 470 self._writeElement(root)) 471 472 root = XML(xml) 473 self.etree.strip_tags(ElementTree(root), Comment, PI) 474 self.assertEqual(_bytes('<test>TESTXT</test>'), 475 self._writeElement(root))
476
477 - def test_strip_tags_doc_style(self):
478 XML = self.etree.XML 479 xml = _bytes(''' 480 <div> 481 <div> 482 I like <strong>sheep</strong>. 483 <br/> 484 I like lots of <strong>sheep</strong>. 485 <br/> 486 Click <a href="http://www.sheep.com">here</a> 487 for <a href="http://www.sheep.com">those</a> sheep. 488 <br/> 489 </div> 490 </div> 491 '''.strip()) 492 493 root = XML(xml) 494 self.etree.strip_tags(root, 'a') 495 self.assertEqual(re.sub(_bytes('</?a[^>]*>'), _bytes(''), xml).replace(_bytes('<br/>'), _bytes('<br></br>')), 496 self._writeElement(root)) 497 498 root = XML(xml) 499 self.etree.strip_tags(root, 'a', 'br') 500 self.assertEqual(re.sub(_bytes('</?a[^>]*>'), _bytes(''), 501 re.sub(_bytes('<br[^>]*>'), _bytes(''), xml)), 502 self._writeElement(root))
503
504 - def test_strip_tags_ns(self):
505 XML = self.etree.XML 506 xml = _bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"/>CT</b>BT</n:a>AT<x>X<a>A<b xmlns="urn:a"/>BT<c xmlns="urn:x"/>CT</a>AT</x>XT</test>') 507 508 root = XML(xml) 509 self.etree.strip_tags(root, 'a') 510 self.assertEqual(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>XA<b xmlns="urn:a"></b>BT<c xmlns="urn:x"></c>CTAT</x>XT</test>'), 511 self._writeElement(root)) 512 513 root = XML(xml) 514 self.etree.strip_tags(root, '{urn:a}b', 'c') 515 self.assertEqual(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 516 self._writeElement(root)) 517 518 root = XML(xml) 519 self.etree.strip_tags(root, '{urn:a}*', 'c') 520 self.assertEqual(_bytes('<test>TESTA<b>B<c xmlns="urn:c"></c>CT</b>BTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 521 self._writeElement(root))
522
523 - def test_strip_tags_and_remove(self):
524 # previously crashed 525 HTML = self.etree.HTML 526 root = HTML(_bytes('<div><h1>title</h1> <b>foo</b> <p>boo</p></div>'))[0][0] 527 self.assertEqual(_bytes('<div><h1>title</h1> <b>foo</b> <p>boo</p></div>'), 528 self.etree.tostring(root)) 529 self.etree.strip_tags(root, 'b') 530 self.assertEqual(_bytes('<div><h1>title</h1> foo <p>boo</p></div>'), 531 self.etree.tostring(root)) 532 root.remove(root[0]) 533 self.assertEqual(_bytes('<div><p>boo</p></div>'), 534 self.etree.tostring(root))
535
536 - def test_pi(self):
537 # lxml.etree separates target and text 538 Element = self.etree.Element 539 SubElement = self.etree.SubElement 540 ProcessingInstruction = self.etree.ProcessingInstruction 541 542 a = Element('a') 543 a.append(ProcessingInstruction('foo', 'some more text')) 544 self.assertEqual(a[0].target, 'foo') 545 self.assertEqual(a[0].text, 'some more text')
546
547 - def test_pi_parse(self):
548 XML = self.etree.XML 549 root = XML(_bytes("<test><?mypi my test ?></test>")) 550 self.assertEqual(root[0].target, "mypi") 551 self.assertEqual(root[0].text, "my test ")
552
554 XML = self.etree.XML 555 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>")) 556 self.assertEqual(root[0].target, "mypi") 557 self.assertEqual(root[0].get('my'), "1") 558 self.assertEqual(root[0].get('test'), " abc ") 559 self.assertEqual(root[0].get('quotes'), "' '") 560 self.assertEqual(root[0].get('only'), None) 561 self.assertEqual(root[0].get('names'), None) 562 self.assertEqual(root[0].get('nope'), None)
563
565 XML = self.etree.XML 566 root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>")) 567 self.assertEqual(root[0].target, "mypi") 568 self.assertEqual(root[0].attrib['my'], "1") 569 self.assertEqual(root[0].attrib['test'], " abc ") 570 self.assertEqual(root[0].attrib['quotes'], "' '") 571 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only') 572 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names') 573 self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
574
575 - def test_deepcopy_pi(self):
576 # previously caused a crash 577 ProcessingInstruction = self.etree.ProcessingInstruction 578 579 a = ProcessingInstruction("PI", "ONE") 580 b = copy.deepcopy(a) 581 b.text = "ANOTHER" 582 583 self.assertEqual('ONE', a.text) 584 self.assertEqual('ANOTHER', b.text)
585
587 XML = self.etree.XML 588 tostring = self.etree.tostring 589 root = XML(_bytes("<?mypi my test ?><test/><!--comment -->")) 590 tree1 = self.etree.ElementTree(root) 591 self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"), 592 tostring(tree1)) 593 594 tree2 = copy.deepcopy(tree1) 595 self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"), 596 tostring(tree2)) 597 598 root2 = copy.deepcopy(tree1.getroot()) 599 self.assertEqual(_bytes("<test/>"), 600 tostring(root2))
601
603 XML = self.etree.XML 604 tostring = self.etree.tostring 605 xml = _bytes('<!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>') 606 root = XML(xml) 607 tree1 = self.etree.ElementTree(root) 608 self.assertEqual(xml, tostring(tree1)) 609 610 tree2 = copy.deepcopy(tree1) 611 self.assertEqual(xml, tostring(tree2)) 612 613 root2 = copy.deepcopy(tree1.getroot()) 614 self.assertEqual(_bytes("<test/>"), 615 tostring(root2))
616
617 - def test_deepcopy_pi_dtd(self):
618 XML = self.etree.XML 619 tostring = self.etree.tostring 620 xml = _bytes('<!-- comment --><!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>') 621 root = XML(xml) 622 tree1 = self.etree.ElementTree(root) 623 self.assertEqual(xml, tostring(tree1)) 624 625 tree2 = copy.deepcopy(tree1) 626 self.assertEqual(xml, tostring(tree2))
627
628 - def test_parse_remove_comments(self):
629 fromstring = self.etree.fromstring 630 tostring = self.etree.tostring 631 XMLParser = self.etree.XMLParser 632 633 xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 634 parser = XMLParser(remove_comments=True) 635 root = fromstring(xml, parser) 636 self.assertEqual( 637 _bytes('<a><b><c/></b></a>'), 638 tostring(root))
639
640 - def test_parse_remove_pis(self):
641 parse = self.etree.parse 642 tostring = self.etree.tostring 643 XMLParser = self.etree.XMLParser 644 645 xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>') 646 647 f = BytesIO(xml) 648 tree = parse(f) 649 self.assertEqual( 650 xml, 651 tostring(tree)) 652 653 parser = XMLParser(remove_pis=True) 654 tree = parse(f, parser) 655 self.assertEqual( 656 _bytes('<a><b><c/></b></a>'), 657 tostring(tree))
658
660 # ET raises IOError only 661 parse = self.etree.parse 662 self.assertRaises(TypeError, parse, 'notthere.xml', object())
663
665 # ET removes comments 666 iterparse = self.etree.iterparse 667 tostring = self.etree.tostring 668 669 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 670 events = list(iterparse(f)) 671 root = events[-1][1] 672 self.assertEqual(3, len(events)) 673 self.assertEqual( 674 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 675 tostring(root))
676
677 - def test_iterparse_comments(self):
678 # ET removes comments 679 iterparse = self.etree.iterparse 680 tostring = self.etree.tostring 681 682 def name(event, el): 683 if event == 'comment': 684 return el.text 685 else: 686 return el.tag
687 688 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 689 events = list(iterparse(f, events=('end', 'comment'))) 690 root = events[-1][1] 691 self.assertEqual(6, len(events)) 692 self.assertEqual(['A', ' B ', 'c', 'b', 'C', 'a'], 693 [ name(*item) for item in events ]) 694 self.assertEqual( 695 _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 696 tostring(root))
697
698 - def test_iterparse_pis(self):
699 # ET removes pis 700 iterparse = self.etree.iterparse 701 tostring = self.etree.tostring 702 ElementTree = self.etree.ElementTree 703 704 def name(event, el): 705 if event == 'pi': 706 return el.target, el.text 707 else: 708 return el.tag
709 710 f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>') 711 events = list(iterparse(f, events=('end', 'pi'))) 712 root = events[-2][1] 713 self.assertEqual(8, len(events)) 714 self.assertEqual([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b', 715 ('pid','d'), 'a', ('pie','e')], 716 [ name(*item) for item in events ]) 717 self.assertEqual( 718 _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'), 719 tostring(ElementTree(root))) 720
721 - def test_iterparse_remove_comments(self):
722 iterparse = self.etree.iterparse 723 tostring = self.etree.tostring 724 725 f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 726 events = list(iterparse(f, remove_comments=True, 727 events=('end', 'comment'))) 728 root = events[-1][1] 729 self.assertEqual(3, len(events)) 730 self.assertEqual(['c', 'b', 'a'], 731 [ el.tag for (event, el) in events ]) 732 self.assertEqual( 733 _bytes('<a><b><c/></b></a>'), 734 tostring(root))
735
736 - def test_iterparse_broken(self):
737 iterparse = self.etree.iterparse 738 f = BytesIO('<a><b><c/></a>') 739 # ET raises ExpatError, lxml raises XMLSyntaxError 740 self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
741
742 - def test_iterparse_broken_recover(self):
743 iterparse = self.etree.iterparse 744 f = BytesIO('<a><b><c/></a>') 745 it = iterparse(f, events=('start', 'end'), recover=True) 746 events = [(ev, el.tag) for ev, el in it] 747 root = it.root 748 self.assertTrue(root is not None) 749 750 self.assertEqual(1, events.count(('start', 'a'))) 751 self.assertEqual(1, events.count(('end', 'a'))) 752 753 self.assertEqual(1, events.count(('start', 'b'))) 754 self.assertEqual(1, events.count(('end', 'b'))) 755 756 self.assertEqual(1, events.count(('start', 'c'))) 757 self.assertEqual(1, events.count(('end', 'c')))
758
759 - def test_iterparse_broken_multi_recover(self):
760 iterparse = self.etree.iterparse 761 f = BytesIO('<a><b><c/></d><b><c/></a></b>') 762 it = iterparse(f, events=('start', 'end'), recover=True) 763 events = [(ev, el.tag) for ev, el in it] 764 root = it.root 765 self.assertTrue(root is not None) 766 767 self.assertEqual(1, events.count(('start', 'a'))) 768 self.assertEqual(1, events.count(('end', 'a'))) 769 770 self.assertEqual(2, events.count(('start', 'b'))) 771 self.assertEqual(2, events.count(('end', 'b'))) 772 773 self.assertEqual(2, events.count(('start', 'c'))) 774 self.assertEqual(2, events.count(('end', 'c')))
775
776 - def test_iterparse_strip(self):
777 iterparse = self.etree.iterparse 778 f = BytesIO(""" 779 <a> \n \n <b> b test </b> \n 780 781 \n\t <c> \n </c> </a> \n """) 782 iterator = iterparse(f, remove_blank_text=True) 783 text = [ (element.text, element.tail) 784 for event, element in iterator ] 785 self.assertEqual( 786 [(" b test ", None), (" \n ", None), (None, None)], 787 text)
788
789 - def test_iterparse_tag(self):
790 iterparse = self.etree.iterparse 791 f = BytesIO('<a><b><d/></b><c/></a>') 792 793 iterator = iterparse(f, tag="b", events=('start', 'end')) 794 events = list(iterator) 795 root = iterator.root 796 self.assertEqual( 797 [('start', root[0]), ('end', root[0])], 798 events)
799
800 - def test_iterparse_tag_all(self):
801 iterparse = self.etree.iterparse 802 f = BytesIO('<a><b><d/></b><c/></a>') 803 804 iterator = iterparse(f, tag="*", events=('start', 'end')) 805 events = list(iterator) 806 self.assertEqual( 807 8, 808 len(events))
809
810 - def test_iterparse_tag_ns(self):
811 iterparse = self.etree.iterparse 812 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 813 814 iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end')) 815 events = list(iterator) 816 root = iterator.root 817 self.assertEqual( 818 [('start', root[0]), ('end', root[0])], 819 events)
820
821 - def test_iterparse_tag_ns_empty(self):
822 iterparse = self.etree.iterparse 823 f = BytesIO('<a><b><d/></b><c/></a>') 824 iterator = iterparse(f, tag="{}b", events=('start', 'end')) 825 events = list(iterator) 826 root = iterator.root 827 self.assertEqual( 828 [('start', root[0]), ('end', root[0])], 829 events) 830 831 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 832 iterator = iterparse(f, tag="{}b", events=('start', 'end')) 833 events = list(iterator) 834 root = iterator.root 835 self.assertEqual([], events)
836
837 - def test_iterparse_tag_ns_all(self):
838 iterparse = self.etree.iterparse 839 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 840 iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end')) 841 events = list(iterator) 842 self.assertEqual(8, len(events))
843
844 - def test_iterparse_tag_ns_empty_all(self):
845 iterparse = self.etree.iterparse 846 f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 847 iterator = iterparse(f, tag="{}*", events=('start', 'end')) 848 events = list(iterator) 849 self.assertEqual([], events) 850 851 f = BytesIO('<a><b><d/></b><c/></a>') 852 iterator = iterparse(f, tag="{}*", events=('start', 'end')) 853 events = list(iterator) 854 self.assertEqual(8, len(events))
855
856 - def test_iterparse_encoding_error(self):
857 text = _str('Søk på nettet') 858 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 859 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 860 ).encode('iso-8859-1') 861 862 self.assertRaises(self.etree.ParseError, 863 list, self.etree.iterparse(BytesIO(xml_latin1)))
864
865 - def test_iterparse_encoding_8bit_override(self):
866 text = _str('Søk på nettet', encoding="UTF-8") 867 wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 868 xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 869 ).encode('iso-8859-1') 870 871 iterator = self.etree.iterparse(BytesIO(xml_latin1), 872 encoding="iso-8859-1") 873 self.assertEqual(1, len(list(iterator))) 874 875 a = iterator.root 876 self.assertEqual(a.text, text)
877
878 - def test_iterparse_keep_cdata(self):
879 tostring = self.etree.tostring 880 f = BytesIO('<root><![CDATA[test]]></root>') 881 context = self.etree.iterparse(f, strip_cdata=False) 882 content = [ el.text for event,el in context ] 883 884 self.assertEqual(['test'], content) 885 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 886 tostring(context.root))
887
888 - def test_parser_encoding_unknown(self):
889 self.assertRaises( 890 LookupError, self.etree.XMLParser, encoding="hopefully unknown")
891
892 - def test_parser_encoding(self):
893 self.etree.XMLParser(encoding="ascii") 894 self.etree.XMLParser(encoding="utf-8") 895 self.etree.XMLParser(encoding="iso-8859-1")
896
897 - def test_feed_parser_recover(self):
898 parser = self.etree.XMLParser(recover=True) 899 900 parser.feed('<?xml version=') 901 parser.feed('"1.0"?><ro') 902 parser.feed('ot><') 903 parser.feed('a test="works"') 904 parser.feed('><othertag/></root') # <a> not closed! 905 parser.feed('>') 906 907 root = parser.close() 908 909 self.assertEqual(root.tag, "root") 910 self.assertEqual(len(root), 1) 911 self.assertEqual(root[0].tag, "a") 912 self.assertEqual(root[0].get("test"), "works") 913 self.assertEqual(len(root[0]), 1) 914 self.assertEqual(root[0][0].tag, "othertag")
915 # FIXME: would be nice to get some errors logged ... 916 #self.assertTrue(len(parser.error_log) > 0, "error log is empty") 917
918 - def test_feed_parser_recover_no_id_dict(self):
919 # test that recover mode plays nicely with the no-id-dict setup 920 parser = self.etree.XMLParser(recover=True, collect_ids=False) 921 922 parser.feed('<?xml version=') 923 parser.feed('"1.0"?><ro') 924 parser.feed('ot xml:id="123"><') 925 parser.feed('a test="works" xml:id=') 926 parser.feed('"321"><othertag/></root') # <a> not closed! 927 parser.feed('>') 928 929 root = parser.close() 930 931 self.assertEqual(root.tag, "root") 932 self.assertEqual(len(root), 1) 933 self.assertEqual(root[0].tag, "a") 934 self.assertEqual(root[0].get("test"), "works") 935 self.assertEqual(root[0].attrib, { 936 'test': 'works', 937 '{http://www.w3.org/XML/1998/namespace}id': '321'}) 938 self.assertEqual(len(root[0]), 1) 939 self.assertEqual(root[0][0].tag, "othertag")
940 # FIXME: would be nice to get some errors logged ... 941 #self.assertTrue(len(parser.error_log) > 0, "error log is empty") 942
943 - def test_elementtree_parser_target_type_error(self):
944 assertEqual = self.assertEqual 945 assertFalse = self.assertFalse 946 947 events = [] 948 class Target(object): 949 def start(self, tag, attrib): 950 events.append("start") 951 assertFalse(attrib) 952 assertEqual("TAG", tag)
953 def end(self, tag): 954 events.append("end") 955 assertEqual("TAG", tag) 956 def close(self): 957 return "DONE" # no Element! 958 959 parser = self.etree.XMLParser(target=Target()) 960 tree = self.etree.ElementTree() 961 962 self.assertRaises(TypeError, 963 tree.parse, BytesIO("<TAG/>"), parser=parser) 964 self.assertEqual(["start", "end"], events) 965
966 - def test_parser_target_feed_exception(self):
967 # ET doesn't call .close() on errors 968 events = [] 969 class Target(object): 970 def start(self, tag, attrib): 971 events.append("start-" + tag)
972 def end(self, tag): 973 events.append("end-" + tag) 974 if tag == 'a': 975 raise ValueError("dead and gone") 976 def data(self, data): 977 events.append("data-" + data) 978 def close(self): 979 events.append("close") 980 return "DONE" 981 982 parser = self.etree.XMLParser(target=Target()) 983 984 try: 985 parser.feed(_bytes('<root>A<a>ca</a>B</root>')) 986 done = parser.close() 987 self.fail("error expected, but parsing succeeded") 988 except ValueError: 989 done = 'value error received as expected' 990 991 self.assertEqual(["start-root", "data-A", "start-a", 992 "data-ca", "end-a", "close"], 993 events) 994
995 - def test_parser_target_fromstring_exception(self):
996 # ET doesn't call .close() on errors 997 events = [] 998 class Target(object): 999 def start(self, tag, attrib): 1000 events.append("start-" + tag)
1001 def end(self, tag): 1002 events.append("end-" + tag) 1003 if tag == 'a': 1004 raise ValueError("dead and gone") 1005 def data(self, data): 1006 events.append("data-" + data) 1007 def close(self): 1008 events.append("close") 1009 return "DONE" 1010 1011 parser = self.etree.XMLParser(target=Target()) 1012 1013 try: 1014 done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'), 1015 parser=parser) 1016 self.fail("error expected, but parsing succeeded") 1017 except ValueError: 1018 done = 'value error received as expected' 1019 1020 self.assertEqual(["start-root", "data-A", "start-a", 1021 "data-ca", "end-a", "close"], 1022 events) 1023
1024 - def test_parser_target_feed_no_id_dict(self):
1025 # test that target parsing works nicely with the no-id-hash setup 1026 events = [] 1027 class Target(object): 1028 def start(self, tag, attrib): 1029 events.append("start-" + tag)
1030 def end(self, tag): 1031 events.append("end-" + tag) 1032 def data(self, data): 1033 events.append("data-" + data) 1034 def comment(self, text): 1035 events.append("comment-" + text) 1036 def close(self): 1037 return "DONE" 1038 1039 parser = self.etree.XMLParser(target=Target(), collect_ids=False) 1040 1041 parser.feed(_bytes('<!--a--><root xml:id="123">A<!--b-->')) 1042 parser.feed(_bytes('<sub xml:id="321"/>B</root>')) 1043 done = parser.close() 1044 1045 self.assertEqual("DONE", done) 1046 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b", 1047 "start-sub", "end-sub", "data-B", "end-root"], 1048 events) 1049
1050 - def test_parser_target_comment(self):
1051 events = [] 1052 class Target(object): 1053 def start(self, tag, attrib): 1054 events.append("start-" + tag)
1055 def end(self, tag): 1056 events.append("end-" + tag) 1057 def data(self, data): 1058 events.append("data-" + data) 1059 def comment(self, text): 1060 events.append("comment-" + text) 1061 def close(self): 1062 return "DONE" 1063 1064 parser = self.etree.XMLParser(target=Target()) 1065 1066 parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->')) 1067 done = parser.close() 1068 1069 self.assertEqual("DONE", done) 1070 self.assertEqual(["comment-a", "start-root", "data-A", "comment-b", 1071 "start-sub", "end-sub", "comment-c", "data-B", 1072 "end-root", "comment-d"], 1073 events) 1074
1075 - def test_parser_target_pi(self):
1076 events = [] 1077 class Target(object): 1078 def start(self, tag, attrib): 1079 events.append("start-" + tag)
1080 def end(self, tag): 1081 events.append("end-" + tag) 1082 def data(self, data): 1083 events.append("data-" + data) 1084 def pi(self, target, data): 1085 events.append("pi-" + target + "-" + data) 1086 def close(self): 1087 return "DONE" 1088 1089 parser = self.etree.XMLParser(target=Target()) 1090 1091 parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>')) 1092 done = parser.close() 1093 1094 self.assertEqual("DONE", done) 1095 self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b", 1096 "data-B", "end-root", "pi-test-c"], 1097 events) 1098
1099 - def test_parser_target_cdata(self):
1100 events = [] 1101 class Target(object): 1102 def start(self, tag, attrib): 1103 events.append("start-" + tag)
1104 def end(self, tag): 1105 events.append("end-" + tag) 1106 def data(self, data): 1107 events.append("data-" + data) 1108 def close(self): 1109 return "DONE" 1110 1111 parser = self.etree.XMLParser(target=Target(), 1112 strip_cdata=False) 1113 1114 parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>')) 1115 done = parser.close() 1116 1117 self.assertEqual("DONE", done) 1118 self.assertEqual(["start-root", "data-A", "start-a", 1119 "data-ca", "end-a", "data-B", "end-root"], 1120 events) 1121
1122 - def test_parser_target_recover(self):
1123 events = [] 1124 class Target(object): 1125 def start(self, tag, attrib): 1126 events.append("start-" + tag)
1127 def end(self, tag): 1128 events.append("end-" + tag) 1129 def data(self, data): 1130 events.append("data-" + data) 1131 def close(self): 1132 events.append("close") 1133 return "DONE" 1134 1135 parser = self.etree.XMLParser(target=Target(), 1136 recover=True) 1137 1138 parser.feed(_bytes('<root>A<a>ca</a>B</not-root>')) 1139 done = parser.close() 1140 1141 self.assertEqual("DONE", done) 1142 self.assertEqual(["start-root", "data-A", "start-a", 1143 "data-ca", "end-a", "data-B", 1144 "end-root", "close"], 1145 events) 1146
1147 - def test_iterwalk_tag(self):
1148 iterwalk = self.etree.iterwalk 1149 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 1150 1151 iterator = iterwalk(root, tag="b", events=('start', 'end')) 1152 events = list(iterator) 1153 self.assertEqual( 1154 [('start', root[0]), ('end', root[0])], 1155 events)
1156
1157 - def test_iterwalk_tag_all(self):
1158 iterwalk = self.etree.iterwalk 1159 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 1160 1161 iterator = iterwalk(root, tag="*", events=('start', 'end')) 1162 events = list(iterator) 1163 self.assertEqual( 1164 8, 1165 len(events))
1166
1167 - def test_iterwalk(self):
1168 iterwalk = self.etree.iterwalk 1169 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 1170 1171 events = list(iterwalk(root)) 1172 self.assertEqual( 1173 [('end', root[0]), ('end', root[1]), ('end', root)], 1174 events)
1175
1176 - def test_iterwalk_comments_root_element(self):
1177 iterwalk = self.etree.iterwalk 1178 root = self.etree.XML( 1179 b'<!--C0--><a><!--Ca--><b><!--Cb--></b><!--Cc--><c/></a><!--C99-->') 1180 1181 iterator = iterwalk(root, events=('start', 'end', 'comment')) 1182 events = list(iterator) 1183 self.assertEqual( 1184 [('start', root), ('comment', root[0]), 1185 ('start', root[1]), ('comment', root[1][0]), ('end', root[1]), 1186 ('comment', root[2]), ('start', root[3]), ('end', root[3]), 1187 ('end', root), 1188 ], 1189 events)
1190
1191 - def test_iterwalk_comments_tree(self):
1192 iterwalk = self.etree.iterwalk 1193 root = self.etree.XML( 1194 b'<!--C0--><a><!--Ca--><b><!--Cb--></b><!--Cc--><c/></a><!--C99-->') 1195 1196 iterator = iterwalk(self.etree.ElementTree(root), events=('start', 'end', 'comment')) 1197 events = list(iterator) 1198 self.assertEqual( 1199 [('comment', root.getprevious()), 1200 ('start', root), ('comment', root[0]), # <a> 1201 ('start', root[1]), ('comment', root[1][0]), ('end', root[1]), # <b> 1202 ('comment', root[2]), ('start', root[3]), ('end', root[3]), # <c> 1203 ('end', root), ('comment', root.getnext()), 1204 ], 1205 events)
1206
1207 - def test_iterwalk_pis_root_element(self):
1208 iterwalk = self.etree.iterwalk 1209 root = self.etree.XML( 1210 b'<?C0?><a><?Ca?><b><?Cb?></b><?Cc?><c/></a><?C99?>') 1211 1212 iterator = iterwalk(root, events=('start', 'end', 'pi')) 1213 events = list(iterator) 1214 self.assertEqual( 1215 [('start', root), ('pi', root[0]), 1216 ('start', root[1]), ('pi', root[1][0]), ('end', root[1]), 1217 ('pi', root[2]), ('start', root[3]), ('end', root[3]), 1218 ('end', root), 1219 ], 1220 events)
1221
1222 - def test_iterwalk_pis_tree(self):
1223 iterwalk = self.etree.iterwalk 1224 root = self.etree.XML( 1225 b'<?C0?><a><?Ca?><b><?Cb?></b><?Cc?><c/></a><?C99?>') 1226 1227 iterator = iterwalk(self.etree.ElementTree(root), events=('start', 'end', 'pi')) 1228 events = list(iterator) 1229 self.assertEqual( 1230 [('pi', root.getprevious()), 1231 ('start', root), ('pi', root[0]), # <a> 1232 ('start', root[1]), ('pi', root[1][0]), ('end', root[1]), # <b> 1233 ('pi', root[2]), ('start', root[3]), ('end', root[3]), # <c> 1234 ('end', root), ('pi', root.getnext()), 1235 ], 1236 events)
1237
1238 - def test_iterwalk_pis_comments_tree(self):
1239 iterwalk = self.etree.iterwalk 1240 root = self.etree.XML( 1241 b'<!--C0--><?C0?><!--C1--><a><?Ca?><b><!--Cb--></b><?Cc?><c/></a><!--C99--><?C99?>') 1242 1243 iterator = iterwalk(self.etree.ElementTree(root), events=('start', 'end', 'pi', 'comment')) 1244 events = list(iterator) 1245 self.assertEqual( 1246 [('comment', root.getprevious().getprevious().getprevious()), 1247 ('pi', root.getprevious().getprevious()), 1248 ('comment', root.getprevious()), 1249 ('start', root), ('pi', root[0]), # <a> 1250 ('start', root[1]), ('comment', root[1][0]), ('end', root[1]), # <b> 1251 ('pi', root[2]), ('start', root[3]), ('end', root[3]), # <c> 1252 ('end', root), ('comment', root.getnext()), ('pi', root.getnext().getnext()), 1253 ], 1254 events)
1255
1256 - def test_iterwalk_pis_comments_tree_no_events(self):
1257 iterwalk = self.etree.iterwalk 1258 root = self.etree.XML( 1259 b'<!--C0--><?C0?><!--C1--><a><?Ca?><b><!--Cb--></b><?Cc?><c/></a><!--C99--><?C99?>') 1260 1261 iterator = iterwalk(self.etree.ElementTree(root), events=('start', 'end')) 1262 events = list(iterator) 1263 self.assertEqual( 1264 [('start', root), # <a> 1265 ('start', root[1]), ('end', root[1]), # <b> 1266 ('start', root[3]), ('end', root[3]), # <c> 1267 ('end', root), 1268 ], 1269 events)
1270
1271 - def test_iterwalk_start(self):
1272 iterwalk = self.etree.iterwalk 1273 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 1274 1275 iterator = iterwalk(root, events=('start',)) 1276 events = list(iterator) 1277 self.assertEqual( 1278 [('start', root), ('start', root[0]), ('start', root[1])], 1279 events)
1280
1281 - def test_iterwalk_start_end(self):
1282 iterwalk = self.etree.iterwalk 1283 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 1284 1285 iterator = iterwalk(root, events=('start','end')) 1286 events = list(iterator) 1287 self.assertEqual( 1288 [('start', root), ('start', root[0]), ('end', root[0]), 1289 ('start', root[1]), ('end', root[1]), ('end', root)], 1290 events)
1291
1292 - def test_iterwalk_start_tags(self):
1293 iterwalk = self.etree.iterwalk 1294 root = self.etree.XML(_bytes('<a><b></b><c/><b><d/></b></a>')) 1295 1296 iterator = iterwalk(root, events=('start',), tag='b') 1297 events = list(iterator) 1298 self.assertEqual( 1299 [('start', root[0]), ('start', root[2])], 1300 events)
1301
1302 - def test_iterwalk_start_end_tags(self):
1303 iterwalk = self.etree.iterwalk 1304 root = self.etree.XML(_bytes('<a><b></b><c/><b><d/></b></a>')) 1305 1306 iterator = iterwalk(root, events=('start', 'end'), tag='b') 1307 events = list(iterator) 1308 self.assertEqual( 1309 [('start', root[0]), ('end', root[0]), ('start', root[2]), ('end', root[2])], 1310 events)
1311
1312 - def test_iterwalk_start_end_tags_with_root(self):
1313 iterwalk = self.etree.iterwalk 1314 root = self.etree.XML(_bytes('<a><b></b><c/><b><d/></b></a>')) 1315 1316 iterator = iterwalk(root, events=('start', 'end'), tag=('b', 'a')) 1317 events = list(iterator) 1318 self.assertEqual( 1319 [('start', root), 1320 ('start', root[0]), ('end', root[0]), 1321 ('start', root[2]), ('end', root[2]), 1322 ('end', root), 1323 ], 1324 events)
1325
1326 - def test_iterwalk_clear(self):
1327 iterwalk = self.etree.iterwalk 1328 root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 1329 1330 iterator = iterwalk(root) 1331 for event, elem in iterator: 1332 elem.clear() 1333 1334 self.assertEqual(0, 1335 len(root))
1336
1337 - def test_iterwalk_attrib_ns(self):
1338 iterwalk = self.etree.iterwalk 1339 root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>')) 1340 1341 attr_name = '{testns}bla' 1342 events = [] 1343 iterator = iterwalk(root, events=('start','end','start-ns','end-ns')) 1344 for event, elem in iterator: 1345 events.append(event) 1346 if event == 'start': 1347 if elem.tag != '{ns1}a': 1348 elem.set(attr_name, 'value') 1349 1350 self.assertEqual( 1351 ['start-ns', 'start', 'start', 'start-ns', 'start', 1352 'end', 'end-ns', 'end', 'end', 'end-ns'], 1353 events) 1354 1355 self.assertEqual( 1356 None, 1357 root.get(attr_name)) 1358 self.assertEqual( 1359 'value', 1360 root[0].get(attr_name))
1361
1362 - def test_iterwalk_end_skip(self):
1363 iterwalk = self.etree.iterwalk 1364 root = self.etree.XML(_bytes('<a><b><c/></b><d><e/></d></a>')) 1365 1366 iterator = iterwalk(root) 1367 tags = [] 1368 for event, elem in iterator: 1369 tags.append(elem.tag) 1370 # requesting a skip after an 'end' event should never have an effect 1371 iterator.skip_subtree() 1372 1373 self.assertEqual(['c', 'b', 'e', 'd', 'a'], tags)
1374
1375 - def test_iterwalk_start_end_skip(self):
1376 iterwalk = self.etree.iterwalk 1377 root = self.etree.XML(_bytes('<a><b><c/></b><d><e/></d></a>')) 1378 1379 iterator = iterwalk(root, events=('start', 'end')) 1380 tags = [] 1381 for event, elem in iterator: 1382 tags.append((event, elem.tag)) 1383 if elem.tag in ('b', 'e'): 1384 # skipping should only have an effect on 'start', not on 'end' 1385 iterator.skip_subtree() 1386 1387 self.assertEqual( 1388 [('start', 'a'), 1389 ('start', 'b'), ('end', 'b'), # ignored child 'c' 1390 ('start', 'd'), 1391 ('start', 'e'), ('end', 'e'), 1392 ('end', 'd'), 1393 ('end', 'a')], 1394 tags)
1395
1396 - def test_iterwalk_ns_skip(self):
1397 iterwalk = self.etree.iterwalk 1398 root = self.etree.XML(_bytes( 1399 '<a xmlns="ns1"><b xmlns="nsb"><c xmlns="ns2"/></b><d xmlns="ns2"><e/></d></a>')) 1400 1401 events = [] 1402 iterator = iterwalk(root, events=('start','start-ns','end-ns')) 1403 for event, elem in iterator: 1404 if event in ('start-ns', 'end-ns'): 1405 events.append((event, elem)) 1406 if event == 'start-ns' and elem == ('', 'nsb'): 1407 events.append('skip') 1408 iterator.skip_subtree() 1409 else: 1410 events.append((event, elem.tag)) 1411 1412 self.assertEqual( 1413 [('start-ns', ('', 'ns1')), 1414 ('start', '{ns1}a'), 1415 ('start-ns', ('', 'nsb')), 1416 'skip', 1417 ('start', '{nsb}b'), 1418 ('end-ns', None), 1419 ('start-ns', ('', 'ns2')), 1420 ('start', '{ns2}d'), 1421 ('start', '{ns2}e'), 1422 ('end-ns', None), 1423 ('end-ns', None) 1424 ], 1425 events)
1426
1427 - def test_iterwalk_getiterator(self):
1428 iterwalk = self.etree.iterwalk 1429 root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 1430 1431 counts = [] 1432 for event, elem in iterwalk(root): 1433 counts.append(len(list(elem.getiterator()))) 1434 self.assertEqual( 1435 [1,2,1,4], 1436 counts)
1437
1438 - def test_resolve_string_dtd(self):
1439 parse = self.etree.parse 1440 parser = self.etree.XMLParser(dtd_validation=True) 1441 assertEqual = self.assertEqual 1442 test_url = _str("__nosuch.dtd") 1443 1444 class MyResolver(self.etree.Resolver): 1445 def resolve(self, url, id, context): 1446 assertEqual(url, test_url) 1447 return self.resolve_string( 1448 _str('''<!ENTITY myentity "%s"> 1449 <!ELEMENT doc ANY>''') % url, context)
1450 1451 parser.resolvers.add(MyResolver()) 1452 1453 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1454 tree = parse(StringIO(xml), parser) 1455 root = tree.getroot() 1456 self.assertEqual(root.text, test_url) 1457
1458 - def test_resolve_bytes_dtd(self):
1459 parse = self.etree.parse 1460 parser = self.etree.XMLParser(dtd_validation=True) 1461 assertEqual = self.assertEqual 1462 test_url = _str("__nosuch.dtd") 1463 1464 class MyResolver(self.etree.Resolver): 1465 def resolve(self, url, id, context): 1466 assertEqual(url, test_url) 1467 return self.resolve_string( 1468 (_str('''<!ENTITY myentity "%s"> 1469 <!ELEMENT doc ANY>''') % url).encode('utf-8'), 1470 context)
1471 1472 parser.resolvers.add(MyResolver()) 1473 1474 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1475 tree = parse(StringIO(xml), parser) 1476 root = tree.getroot() 1477 self.assertEqual(root.text, test_url) 1478
1479 - def test_resolve_filelike_dtd(self):
1480 parse = self.etree.parse 1481 parser = self.etree.XMLParser(dtd_validation=True) 1482 assertEqual = self.assertEqual 1483 test_url = _str("__nosuch.dtd") 1484 1485 class MyResolver(self.etree.Resolver): 1486 def resolve(self, url, id, context): 1487 assertEqual(url, test_url) 1488 return self.resolve_file( 1489 SillyFileLike( 1490 _str('''<!ENTITY myentity "%s"> 1491 <!ELEMENT doc ANY>''') % url), context)
1492 1493 parser.resolvers.add(MyResolver()) 1494 1495 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1496 tree = parse(StringIO(xml), parser) 1497 root = tree.getroot() 1498 self.assertEqual(root.text, test_url) 1499
1500 - def test_resolve_filename_dtd(self):
1501 parse = self.etree.parse 1502 parser = self.etree.XMLParser(attribute_defaults=True) 1503 assertEqual = self.assertEqual 1504 test_url = _str("__nosuch.dtd") 1505 1506 class MyResolver(self.etree.Resolver): 1507 def resolve(self, url, id, context): 1508 assertEqual(url, test_url) 1509 return self.resolve_filename( 1510 fileInTestDir('test.dtd'), context)
1511 1512 parser.resolvers.add(MyResolver()) 1513 1514 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1515 tree = parse(StringIO(xml), parser) 1516 root = tree.getroot() 1517 self.assertEqual( 1518 root.attrib, {'default': 'valueA'}) 1519 self.assertEqual( 1520 root[0].attrib, {'default': 'valueB'}) 1521
1522 - def test_resolve_filename_dtd_relative(self):
1523 parse = self.etree.parse 1524 parser = self.etree.XMLParser(attribute_defaults=True) 1525 assertEqual = self.assertEqual 1526 test_url = _str("__nosuch.dtd") 1527 1528 class MyResolver(self.etree.Resolver): 1529 def resolve(self, url, id, context): 1530 expected = fileUrlInTestDir(test_url) 1531 url = url.replace('file://', 'file:') # depends on libxml2 version 1532 expected = expected.replace('file://', 'file:') 1533 assertEqual(url, expected) 1534 return self.resolve_filename( 1535 fileUrlInTestDir('test.dtd'), context)
1536 1537 parser.resolvers.add(MyResolver()) 1538 1539 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1540 tree = parse(StringIO(xml), parser, 1541 base_url=fileUrlInTestDir('__test.xml')) 1542 root = tree.getroot() 1543 self.assertEqual( 1544 root.attrib, {'default': 'valueA'}) 1545 self.assertEqual( 1546 root[0].attrib, {'default': 'valueB'}) 1547
1548 - def test_resolve_file_dtd(self):
1549 parse = self.etree.parse 1550 parser = self.etree.XMLParser(attribute_defaults=True) 1551 assertEqual = self.assertEqual 1552 test_url = _str("__nosuch.dtd") 1553 1554 class MyResolver(self.etree.Resolver): 1555 def resolve(self, url, id, context): 1556 assertEqual(url, test_url) 1557 return self.resolve_file( 1558 open(fileInTestDir('test.dtd'), 'rb'), context)
1559 1560 parser.resolvers.add(MyResolver()) 1561 1562 xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 1563 tree = parse(StringIO(xml), parser) 1564 root = tree.getroot() 1565 self.assertEqual( 1566 root.attrib, {'default': 'valueA'}) 1567 self.assertEqual( 1568 root[0].attrib, {'default': 'valueB'}) 1569
1570 - def test_resolve_empty(self):
1571 parse = self.etree.parse 1572 parser = self.etree.XMLParser(load_dtd=True) 1573 assertEqual = self.assertEqual 1574 test_url = _str("__nosuch.dtd") 1575 1576 class check(object): 1577 resolved = False
1578 1579 class MyResolver(self.etree.Resolver): 1580 def resolve(self, url, id, context): 1581 assertEqual(url, test_url) 1582 check.resolved = True 1583 return self.resolve_empty(context) 1584 1585 parser.resolvers.add(MyResolver()) 1586 1587 xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 1588 self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser) 1589 self.assertTrue(check.resolved) 1590
1591 - def test_resolve_error(self):
1592 parse = self.etree.parse 1593 parser = self.etree.XMLParser(dtd_validation=True) 1594 1595 class _LocalException(Exception): 1596 pass
1597 1598 class MyResolver(self.etree.Resolver): 1599 def resolve(self, url, id, context): 1600 raise _LocalException 1601 1602 parser.resolvers.add(MyResolver()) 1603 1604 xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 1605 self.assertRaises(_LocalException, parse, BytesIO(xml), parser) 1606
1607 - def test_entity_parse(self):
1608 parse = self.etree.parse 1609 tostring = self.etree.tostring 1610 parser = self.etree.XMLParser(resolve_entities=False) 1611 Entity = self.etree.Entity 1612 1613 xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>') 1614 tree = parse(BytesIO(xml), parser) 1615 root = tree.getroot() 1616 self.assertEqual(root[0].tag, Entity) 1617 self.assertEqual(root[0].text, "&myentity;") 1618 self.assertEqual(root[0].tail, None) 1619 self.assertEqual(root[0].name, "myentity") 1620 1621 self.assertEqual(_bytes('<doc>&myentity;</doc>'), 1622 tostring(root))
1623
1624 - def test_entity_restructure(self):
1625 xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp "&#160;"> ]> 1626 <root> 1627 <child1/> 1628 <child2/> 1629 <child3>&nbsp;</child3> 1630 </root>''') 1631 1632 parser = self.etree.XMLParser(resolve_entities=False) 1633 root = etree.fromstring(xml, parser) 1634 self.assertEqual([ el.tag for el in root ], 1635 ['child1', 'child2', 'child3']) 1636 1637 root[0] = root[-1] 1638 self.assertEqual([ el.tag for el in root ], 1639 ['child3', 'child2']) 1640 self.assertEqual(root[0][0].text, '&nbsp;') 1641 self.assertEqual(root[0][0].name, 'nbsp')
1642
1643 - def test_entity_append(self):
1644 Entity = self.etree.Entity 1645 Element = self.etree.Element 1646 tostring = self.etree.tostring 1647 1648 root = Element("root") 1649 root.append( Entity("test") ) 1650 1651 self.assertEqual(root[0].tag, Entity) 1652 self.assertEqual(root[0].text, "&test;") 1653 self.assertEqual(root[0].tail, None) 1654 self.assertEqual(root[0].name, "test") 1655 1656 self.assertEqual(_bytes('<root>&test;</root>'), 1657 tostring(root))
1658
1659 - def test_entity_append_parsed(self):
1660 Entity = self.etree.Entity 1661 Element = self.etree.Element 1662 parser = self.etree.XMLParser(resolve_entities=False) 1663 entity = self.etree.XML('''<!DOCTYPE data [ 1664 <!ENTITY a "a"> 1665 <!ENTITY b "&a;"> 1666 ]> 1667 <data>&b;</data> 1668 ''', parser) 1669 1670 el = Element('test') 1671 el.append(entity) 1672 self.assertEqual(el.tag, 'test') 1673 self.assertEqual(el[0].tag, 'data') 1674 self.assertEqual(el[0][0].tag, Entity) 1675 self.assertEqual(el[0][0].name, 'b')
1676
1677 - def test_entity_values(self):
1678 Entity = self.etree.Entity 1679 self.assertEqual(Entity("test").text, '&test;') 1680 self.assertEqual(Entity("#17683").text, '&#17683;') 1681 self.assertEqual(Entity("#x1768").text, '&#x1768;') 1682 self.assertEqual(Entity("#x98AF").text, '&#x98AF;')
1683
1684 - def test_entity_error(self):
1685 Entity = self.etree.Entity 1686 self.assertRaises(ValueError, Entity, 'a b c') 1687 self.assertRaises(ValueError, Entity, 'a,b') 1688 self.assertRaises(ValueError, Entity, 'a\0b') 1689 self.assertRaises(ValueError, Entity, '#abc') 1690 self.assertRaises(ValueError, Entity, '#xxyz')
1691
1692 - def test_cdata(self):
1693 CDATA = self.etree.CDATA 1694 Element = self.etree.Element 1695 tostring = self.etree.tostring 1696 1697 root = Element("root") 1698 root.text = CDATA('test') 1699 1700 self.assertEqual('test', 1701 root.text) 1702 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 1703 tostring(root))
1704
1705 - def test_cdata_tail(self):
1706 CDATA = self.etree.CDATA 1707 Element = self.etree.Element 1708 SubElement = self.etree.SubElement 1709 tostring = self.etree.tostring 1710 1711 root = Element("root") 1712 child = SubElement(root, 'child') 1713 child.tail = CDATA('test') 1714 1715 self.assertEqual('test', child.tail) 1716 self.assertEqual(_bytes('<root><child/><![CDATA[test]]></root>'), 1717 tostring(root)) 1718 1719 root = Element("root") 1720 root.tail = CDATA('test') 1721 1722 self.assertEqual('test', root.tail) 1723 self.assertEqual(_bytes('<root/><![CDATA[test]]>'), 1724 tostring(root))
1725
1726 - def test_cdata_type(self):
1727 CDATA = self.etree.CDATA 1728 Element = self.etree.Element 1729 root = Element("root") 1730 1731 root.text = CDATA("test") 1732 self.assertEqual('test', root.text) 1733 1734 root.text = CDATA(_str("test")) 1735 self.assertEqual('test', root.text) 1736 1737 self.assertRaises(TypeError, CDATA, 1)
1738
1739 - def test_cdata_errors(self):
1740 CDATA = self.etree.CDATA 1741 Element = self.etree.Element 1742 1743 root = Element("root") 1744 cdata = CDATA('test') 1745 1746 self.assertRaises(TypeError, 1747 root.set, 'attr', cdata) 1748 self.assertRaises(TypeError, 1749 operator.setitem, root.attrib, 'attr', cdata)
1750
1751 - def test_cdata_parser(self):
1752 tostring = self.etree.tostring 1753 parser = self.etree.XMLParser(strip_cdata=False) 1754 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1755 1756 self.assertEqual('test', root.text) 1757 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 1758 tostring(root))
1759
1760 - def test_cdata_xpath(self):
1761 tostring = self.etree.tostring 1762 parser = self.etree.XMLParser(strip_cdata=False) 1763 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1764 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 1765 tostring(root)) 1766 1767 self.assertEqual(['test'], root.xpath('//text()'))
1768 1769 # TypeError in etree, AssertionError in ElementTree;
1770 - def test_setitem_assert(self):
1771 Element = self.etree.Element 1772 SubElement = self.etree.SubElement 1773 1774 a = Element('a') 1775 b = SubElement(a, 'b') 1776 1777 self.assertRaises(TypeError, 1778 a.__setitem__, 0, 'foo')
1779
1780 - def test_append_error(self):
1781 Element = self.etree.Element 1782 root = Element('root') 1783 # raises AssertionError in ElementTree 1784 self.assertRaises(TypeError, root.append, None) 1785 self.assertRaises(TypeError, root.extend, [None]) 1786 self.assertRaises(TypeError, root.extend, [Element('one'), None]) 1787 self.assertEqual('one', root[0].tag)
1788
1789 - def test_append_recursive_error(self):
1790 Element = self.etree.Element 1791 SubElement = self.etree.SubElement 1792 root = Element('root') 1793 self.assertRaises(ValueError, root.append, root) 1794 child = SubElement(root, 'child') 1795 self.assertRaises(ValueError, child.append, root) 1796 child2 = SubElement(child, 'child2') 1797 self.assertRaises(ValueError, child2.append, root) 1798 self.assertRaises(ValueError, child2.append, child) 1799 self.assertEqual('child2', root[0][0].tag)
1800
1801 - def test_addnext(self):
1802 Element = self.etree.Element 1803 SubElement = self.etree.SubElement 1804 root = Element('root') 1805 SubElement(root, 'a') 1806 SubElement(root, 'b') 1807 1808 self.assertEqual(['a', 'b'], 1809 [c.tag for c in root]) 1810 root[1].addnext(root[0]) 1811 self.assertEqual(['b', 'a'], 1812 [c.tag for c in root])
1813
1814 - def test_addprevious(self):
1815 Element = self.etree.Element 1816 SubElement = self.etree.SubElement 1817 root = Element('root') 1818 SubElement(root, 'a') 1819 SubElement(root, 'b') 1820 1821 self.assertEqual(['a', 'b'], 1822 [c.tag for c in root]) 1823 root[0].addprevious(root[1]) 1824 self.assertEqual(['b', 'a'], 1825 [c.tag for c in root])
1826
1827 - def test_addnext_cycle(self):
1828 Element = self.etree.Element 1829 SubElement = self.etree.SubElement 1830 root = Element('root') 1831 a = SubElement(root, 'a') 1832 b = SubElement(a, 'b') 1833 # appending parent as sibling is forbidden 1834 self.assertRaises(ValueError, b.addnext, a) 1835 self.assertEqual(['a'], [c.tag for c in root]) 1836 self.assertEqual(['b'], [c.tag for c in a])
1837
1838 - def test_addprevious_cycle(self):
1839 Element = self.etree.Element 1840 SubElement = self.etree.SubElement 1841 root = Element('root') 1842 a = SubElement(root, 'a') 1843 b = SubElement(a, 'b') 1844 # appending parent as sibling is forbidden 1845 self.assertRaises(ValueError, b.addprevious, a) 1846 self.assertEqual(['a'], [c.tag for c in root]) 1847 self.assertEqual(['b'], [c.tag for c in a])
1848
1849 - def test_addnext_cycle_long(self):
1850 Element = self.etree.Element 1851 SubElement = self.etree.SubElement 1852 root = Element('root') 1853 a = SubElement(root, 'a') 1854 b = SubElement(a, 'b') 1855 c = SubElement(b, 'c') 1856 # appending parent as sibling is forbidden 1857 self.assertRaises(ValueError, c.addnext, a)
1858
1859 - def test_addprevious_cycle_long(self):
1860 Element = self.etree.Element 1861 SubElement = self.etree.SubElement 1862 root = Element('root') 1863 a = SubElement(root, 'a') 1864 b = SubElement(a, 'b') 1865 c = SubElement(b, 'c') 1866 # appending parent as sibling is forbidden 1867 self.assertRaises(ValueError, c.addprevious, a)
1868
1869 - def test_addprevious_noops(self):
1870 Element = self.etree.Element 1871 SubElement = self.etree.SubElement 1872 root = Element('root') 1873 a = SubElement(root, 'a') 1874 b = SubElement(root, 'b') 1875 a.addprevious(a) 1876 self.assertEqual('a', root[0].tag) 1877 self.assertEqual('b', root[1].tag) 1878 b.addprevious(b) 1879 self.assertEqual('a', root[0].tag) 1880 self.assertEqual('b', root[1].tag) 1881 b.addprevious(a) 1882 self.assertEqual('a', root[0].tag) 1883 self.assertEqual('b', root[1].tag)
1884
1885 - def test_addnext_noops(self):
1886 Element = self.etree.Element 1887 SubElement = self.etree.SubElement 1888 root = Element('root') 1889 a = SubElement(root, 'a') 1890 b = SubElement(root, 'b') 1891 a.addnext(a) 1892 self.assertEqual('a', root[0].tag) 1893 self.assertEqual('b', root[1].tag) 1894 b.addnext(b) 1895 self.assertEqual('a', root[0].tag) 1896 self.assertEqual('b', root[1].tag) 1897 a.addnext(b) 1898 self.assertEqual('a', root[0].tag) 1899 self.assertEqual('b', root[1].tag)
1900
1901 - def test_addnext_root(self):
1902 Element = self.etree.Element 1903 a = Element('a') 1904 b = Element('b') 1905 self.assertRaises(TypeError, a.addnext, b)
1906
1907 - def test_addprevious_pi(self):
1908 Element = self.etree.Element 1909 SubElement = self.etree.SubElement 1910 PI = self.etree.PI 1911 root = Element('root') 1912 SubElement(root, 'a') 1913 pi = PI('TARGET', 'TEXT') 1914 pi.tail = "TAIL" 1915 1916 self.assertEqual(_bytes('<root><a></a></root>'), 1917 self._writeElement(root)) 1918 root[0].addprevious(pi) 1919 self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'), 1920 self._writeElement(root))
1921
1922 - def test_addprevious_root_pi(self):
1923 Element = self.etree.Element 1924 PI = self.etree.PI 1925 root = Element('root') 1926 pi = PI('TARGET', 'TEXT') 1927 pi.tail = "TAIL" 1928 1929 self.assertEqual(_bytes('<root></root>'), 1930 self._writeElement(root)) 1931 root.addprevious(pi) 1932 self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'), 1933 self._writeElement(root))
1934
1935 - def test_addnext_pi(self):
1936 Element = self.etree.Element 1937 SubElement = self.etree.SubElement 1938 PI = self.etree.PI 1939 root = Element('root') 1940 SubElement(root, 'a') 1941 pi = PI('TARGET', 'TEXT') 1942 pi.tail = "TAIL" 1943 1944 self.assertEqual(_bytes('<root><a></a></root>'), 1945 self._writeElement(root)) 1946 root[0].addnext(pi) 1947 self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'), 1948 self._writeElement(root))
1949
1950 - def test_addnext_root_pi(self):
1951 Element = self.etree.Element 1952 PI = self.etree.PI 1953 root = Element('root') 1954 pi = PI('TARGET', 'TEXT') 1955 pi.tail = "TAIL" 1956 1957 self.assertEqual(_bytes('<root></root>'), 1958 self._writeElement(root)) 1959 root.addnext(pi) 1960 self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'), 1961 self._writeElement(root))
1962
1963 - def test_addnext_comment(self):
1964 Element = self.etree.Element 1965 SubElement = self.etree.SubElement 1966 Comment = self.etree.Comment 1967 root = Element('root') 1968 SubElement(root, 'a') 1969 comment = Comment('TEXT ') 1970 comment.tail = "TAIL" 1971 1972 self.assertEqual(_bytes('<root><a></a></root>'), 1973 self._writeElement(root)) 1974 root[0].addnext(comment) 1975 self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'), 1976 self._writeElement(root))
1977
1978 - def test_addnext_root_comment(self):
1979 Element = self.etree.Element 1980 Comment = self.etree.Comment 1981 root = Element('root') 1982 comment = Comment('TEXT ') 1983 comment.tail = "TAIL" 1984 1985 self.assertEqual(_bytes('<root></root>'), 1986 self._writeElement(root)) 1987 root.addnext(comment) 1988 self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'), 1989 self._writeElement(root))
1990
1991 - def test_addprevious_comment(self):
1992 Element = self.etree.Element 1993 SubElement = self.etree.SubElement 1994 Comment = self.etree.Comment 1995 root = Element('root') 1996 SubElement(root, 'a') 1997 comment = Comment('TEXT ') 1998 comment.tail = "TAIL" 1999 2000 self.assertEqual(_bytes('<root><a></a></root>'), 2001 self._writeElement(root)) 2002 root[0].addprevious(comment) 2003 self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'), 2004 self._writeElement(root))
2005
2006 - def test_addprevious_root_comment(self):
2007 Element = self.etree.Element 2008 Comment = self.etree.Comment 2009 root = Element('root') 2010 comment = Comment('TEXT ') 2011 comment.tail = "TAIL" 2012 2013 self.assertEqual(_bytes('<root></root>'), 2014 self._writeElement(root)) 2015 root.addprevious(comment) 2016 self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'), 2017 self._writeElement(root))
2018 2019 # ET's Elements have items() and key(), but not values()
2020 - def test_attribute_values(self):
2021 XML = self.etree.XML 2022 2023 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')) 2024 values = root.values() 2025 values.sort() 2026 self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
2027 2028 # gives error in ElementTree
2029 - def test_comment_empty(self):
2030 Element = self.etree.Element 2031 Comment = self.etree.Comment 2032 2033 a = Element('a') 2034 a.append(Comment()) 2035 self.assertEqual( 2036 _bytes('<a><!----></a>'), 2037 self._writeElement(a))
2038 2039 # ElementTree ignores comments
2040 - def test_comment_parse_empty(self):
2041 ElementTree = self.etree.ElementTree 2042 tostring = self.etree.tostring 2043 2044 xml = _bytes('<a><b/><!----><c/></a>') 2045 f = BytesIO(xml) 2046 doc = ElementTree(file=f) 2047 a = doc.getroot() 2048 self.assertEqual( 2049 '', 2050 a[1].text) 2051 self.assertEqual( 2052 xml, 2053 tostring(a))
2054 2055 # ElementTree ignores comments
2056 - def test_comment_no_proxy_yet(self):
2057 ElementTree = self.etree.ElementTree 2058 2059 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>') 2060 doc = ElementTree(file=f) 2061 a = doc.getroot() 2062 self.assertEqual( 2063 ' hoi ', 2064 a[1].text)
2065 2066 # does not raise an exception in ElementTree
2067 - def test_comment_immutable(self):
2068 Element = self.etree.Element 2069 Comment = self.etree.Comment 2070 2071 c = Comment() 2072 el = Element('myel') 2073 2074 self.assertRaises(TypeError, c.append, el) 2075 self.assertRaises(TypeError, c.insert, 0, el) 2076 self.assertRaises(TypeError, c.set, "myattr", "test")
2077
2078 - def test_comment_immutable_attrib(self):
2079 c = self.etree.Comment() 2080 self.assertEqual(0, len(c.attrib)) 2081 2082 self.assertFalse(c.attrib.__contains__('nope')) 2083 self.assertFalse('nope' in c.attrib) 2084 self.assertFalse('nope' in c.attrib.keys()) 2085 self.assertFalse('nope' in c.attrib.values()) 2086 self.assertFalse(('nope', 'huhu') in c.attrib.items()) 2087 2088 self.assertEqual([], list(c.attrib)) 2089 self.assertEqual([], list(c.attrib.keys())) 2090 self.assertEqual([], list(c.attrib.items())) 2091 self.assertEqual([], list(c.attrib.values())) 2092 self.assertEqual([], list(c.attrib.iterkeys())) 2093 self.assertEqual([], list(c.attrib.iteritems())) 2094 self.assertEqual([], list(c.attrib.itervalues())) 2095 2096 self.assertEqual('HUHU', c.attrib.pop('nope', 'HUHU')) 2097 self.assertRaises(KeyError, c.attrib.pop, 'nope') 2098 2099 self.assertRaises(KeyError, c.attrib.__getitem__, 'only') 2100 self.assertRaises(KeyError, c.attrib.__getitem__, 'names') 2101 self.assertRaises(KeyError, c.attrib.__getitem__, 'nope') 2102 self.assertRaises(KeyError, c.attrib.__setitem__, 'nope', 'yep') 2103 self.assertRaises(KeyError, c.attrib.__delitem__, 'nope')
2104 2105 # test passing 'None' to dump()
2106 - def test_dump_none(self):
2107 self.assertRaises(TypeError, self.etree.dump, None)
2108
2109 - def test_prefix(self):
2110 ElementTree = self.etree.ElementTree 2111 2112 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 2113 doc = ElementTree(file=f) 2114 a = doc.getroot() 2115 self.assertEqual( 2116 None, 2117 a.prefix) 2118 self.assertEqual( 2119 'foo', 2120 a[0].prefix)
2121
2122 - def test_prefix_default_ns(self):
2123 ElementTree = self.etree.ElementTree 2124 2125 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 2126 doc = ElementTree(file=f) 2127 a = doc.getroot() 2128 self.assertEqual( 2129 None, 2130 a.prefix) 2131 self.assertEqual( 2132 None, 2133 a[0].prefix)
2134
2135 - def test_getparent(self):
2136 Element = self.etree.Element 2137 SubElement = self.etree.SubElement 2138 2139 a = Element('a') 2140 b = SubElement(a, 'b') 2141 c = SubElement(a, 'c') 2142 d = SubElement(b, 'd') 2143 self.assertEqual( 2144 None, 2145 a.getparent()) 2146 self.assertEqual( 2147 a, 2148 b.getparent()) 2149 self.assertEqual( 2150 b.getparent(), 2151 c.getparent()) 2152 self.assertEqual( 2153 b, 2154 d.getparent())
2155
2156 - def test_iterchildren(self):
2157 XML = self.etree.XML 2158 2159 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 2160 result = [] 2161 for el in root.iterchildren(): 2162 result.append(el.tag) 2163 self.assertEqual(['one', 'two', 'three'], result)
2164
2165 - def test_iterchildren_reversed(self):
2166 XML = self.etree.XML 2167 2168 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 2169 result = [] 2170 for el in root.iterchildren(reversed=True): 2171 result.append(el.tag) 2172 self.assertEqual(['three', 'two', 'one'], result)
2173
2174 - def test_iterchildren_tag(self):
2175 XML = self.etree.XML 2176 2177 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 2178 result = [] 2179 for el in root.iterchildren(tag='two'): 2180 result.append(el.text) 2181 self.assertEqual(['Two', 'Bla'], result)
2182
2183 - def test_iterchildren_tag_posarg(self):
2184 XML = self.etree.XML 2185 2186 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 2187 result = [] 2188 for el in root.iterchildren('two'): 2189 result.append(el.text) 2190 self.assertEqual(['Two', 'Bla'], result)
2191
2192 - def test_iterchildren_tag_reversed(self):
2193 XML = self.etree.XML 2194 2195 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 2196 result = [] 2197 for el in root.iterchildren(reversed=True, tag='two'): 2198 result.append(el.text) 2199 self.assertEqual(['Bla', 'Two'], result)
2200
2201 - def test_iterchildren_tag_multiple(self):
2202 XML = self.etree.XML 2203 2204 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 2205 result = [] 2206 for el in root.iterchildren(tag=['two', 'three']): 2207 result.append(el.text) 2208 self.assertEqual(['Two', 'Bla', None], result)
2209
2210 - def test_iterchildren_tag_multiple_posarg(self):
2211 XML = self.etree.XML 2212 2213 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 2214 result = [] 2215 for el in root.iterchildren('two', 'three'): 2216 result.append(el.text) 2217 self.assertEqual(['Two', 'Bla', None], result)
2218
2219 - def test_iterchildren_tag_multiple_reversed(self):
2220 XML = self.etree.XML 2221 2222 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 2223 result = [] 2224 for el in root.iterchildren(reversed=True, tag=['two', 'three']): 2225 result.append(el.text) 2226 self.assertEqual([None, 'Bla', 'Two'], result)
2227
2228 - def test_iterancestors(self):
2229 Element = self.etree.Element 2230 SubElement = self.etree.SubElement 2231 2232 a = Element('a') 2233 b = SubElement(a, 'b') 2234 c = SubElement(a, 'c') 2235 d = SubElement(b, 'd') 2236 self.assertEqual( 2237 [], 2238 list(a.iterancestors())) 2239 self.assertEqual( 2240 [a], 2241 list(b.iterancestors())) 2242 self.assertEqual( 2243 [a], 2244 list(c.iterancestors())) 2245 self.assertEqual( 2246 [b, a], 2247 list(d.iterancestors()))
2248
2249 - def test_iterancestors_tag(self):
2250 Element = self.etree.Element 2251 SubElement = self.etree.SubElement 2252 2253 a = Element('a') 2254 b = SubElement(a, 'b') 2255 c = SubElement(a, 'c') 2256 d = SubElement(b, 'd') 2257 self.assertEqual( 2258 [a], 2259 list(d.iterancestors('a'))) 2260 self.assertEqual( 2261 [a], 2262 list(d.iterancestors(tag='a'))) 2263 2264 self.assertEqual( 2265 [b, a], 2266 list(d.iterancestors('*'))) 2267 self.assertEqual( 2268 [b, a], 2269 list(d.iterancestors(tag='*')))
2270
2271 - def test_iterancestors_tag_multiple(self):
2272 Element = self.etree.Element 2273 SubElement = self.etree.SubElement 2274 2275 a = Element('a') 2276 b = SubElement(a, 'b') 2277 c = SubElement(a, 'c') 2278 d = SubElement(b, 'd') 2279 self.assertEqual( 2280 [b, a], 2281 list(d.iterancestors(tag=('a', 'b')))) 2282 self.assertEqual( 2283 [b, a], 2284 list(d.iterancestors('a', 'b'))) 2285 2286 self.assertEqual( 2287 [], 2288 list(d.iterancestors(tag=('w', 'x', 'y', 'z')))) 2289 self.assertEqual( 2290 [], 2291 list(d.iterancestors('w', 'x', 'y', 'z'))) 2292 2293 self.assertEqual( 2294 [], 2295 list(d.iterancestors(tag=('d', 'x')))) 2296 self.assertEqual( 2297 [], 2298 list(d.iterancestors('d', 'x'))) 2299 2300 self.assertEqual( 2301 [b, a], 2302 list(d.iterancestors(tag=('b', '*')))) 2303 self.assertEqual( 2304 [b, a], 2305 list(d.iterancestors('b', '*'))) 2306 2307 self.assertEqual( 2308 [b], 2309 list(d.iterancestors(tag=('b', 'c')))) 2310 self.assertEqual( 2311 [b], 2312 list(d.iterancestors('b', 'c')))
2313
2314 - def test_iterdescendants(self):
2315 Element = self.etree.Element 2316 SubElement = self.etree.SubElement 2317 2318 a = Element('a') 2319 b = SubElement(a, 'b') 2320 c = SubElement(a, 'c') 2321 d = SubElement(b, 'd') 2322 e = SubElement(c, 'e') 2323 2324 self.assertEqual( 2325 [b, d, c, e], 2326 list(a.iterdescendants())) 2327 self.assertEqual( 2328 [], 2329 list(d.iterdescendants()))
2330
2331 - def test_iterdescendants_tag(self):
2332 Element = self.etree.Element 2333 SubElement = self.etree.SubElement 2334 2335 a = Element('a') 2336 b = SubElement(a, 'b') 2337 c = SubElement(a, 'c') 2338 d = SubElement(b, 'd') 2339 e = SubElement(c, 'e') 2340 2341 self.assertEqual( 2342 [], 2343 list(a.iterdescendants('a'))) 2344 self.assertEqual( 2345 [], 2346 list(a.iterdescendants(tag='a'))) 2347 2348 a2 = SubElement(e, 'a') 2349 self.assertEqual( 2350 [a2], 2351 list(a.iterdescendants('a'))) 2352 2353 self.assertEqual( 2354 [a2], 2355 list(c.iterdescendants('a'))) 2356 self.assertEqual( 2357 [a2], 2358 list(c.iterdescendants(tag='a')))
2359
2360 - def test_iterdescendants_tag_multiple(self):
2361 Element = self.etree.Element 2362 SubElement = self.etree.SubElement 2363 2364 a = Element('a') 2365 b = SubElement(a, 'b') 2366 c = SubElement(a, 'c') 2367 d = SubElement(b, 'd') 2368 e = SubElement(c, 'e') 2369 2370 self.assertEqual( 2371 [b, e], 2372 list(a.iterdescendants(tag=('a', 'b', 'e')))) 2373 self.assertEqual( 2374 [b, e], 2375 list(a.iterdescendants('a', 'b', 'e'))) 2376 2377 a2 = SubElement(e, 'a') 2378 self.assertEqual( 2379 [b, a2], 2380 list(a.iterdescendants(tag=('a', 'b')))) 2381 self.assertEqual( 2382 [b, a2], 2383 list(a.iterdescendants('a', 'b'))) 2384 2385 self.assertEqual( 2386 [], 2387 list(c.iterdescendants(tag=('x', 'y', 'z')))) 2388 self.assertEqual( 2389 [], 2390 list(c.iterdescendants('x', 'y', 'z'))) 2391 2392 self.assertEqual( 2393 [b, d, c, e, a2], 2394 list(a.iterdescendants(tag=('x', 'y', 'z', '*')))) 2395 self.assertEqual( 2396 [b, d, c, e, a2], 2397 list(a.iterdescendants('x', 'y', 'z', '*')))
2398
2399 - def test_getroottree(self):
2400 Element = self.etree.Element 2401 SubElement = self.etree.SubElement 2402 2403 a = Element('a') 2404 b = SubElement(a, 'b') 2405 c = SubElement(a, 'c') 2406 d = SubElement(b, 'd') 2407 self.assertEqual( 2408 a, 2409 a.getroottree().getroot()) 2410 self.assertEqual( 2411 a, 2412 b.getroottree().getroot()) 2413 self.assertEqual( 2414 a, 2415 d.getroottree().getroot())
2416
2417 - def test_getnext(self):
2418 Element = self.etree.Element 2419 SubElement = self.etree.SubElement 2420 2421 a = Element('a') 2422 b = SubElement(a, 'b') 2423 c = SubElement(a, 'c') 2424 self.assertEqual( 2425 None, 2426 a.getnext()) 2427 self.assertEqual( 2428 c, 2429 b.getnext()) 2430 self.assertEqual( 2431 None, 2432 c.getnext())
2433
2434 - def test_getprevious(self):
2435 Element = self.etree.Element 2436 SubElement = self.etree.SubElement 2437 2438 a = Element('a') 2439 b = SubElement(a, 'b') 2440 c = SubElement(a, 'c') 2441 d = SubElement(b, 'd') 2442 self.assertEqual( 2443 None, 2444 a.getprevious()) 2445 self.assertEqual( 2446 b, 2447 c.getprevious()) 2448 self.assertEqual( 2449 None, 2450 b.getprevious())
2451
2452 - def test_itersiblings(self):
2453 Element = self.etree.Element 2454 SubElement = self.etree.SubElement 2455 2456 a = Element('a') 2457 b = SubElement(a, 'b') 2458 c = SubElement(a, 'c') 2459 d = SubElement(b, 'd') 2460 self.assertEqual( 2461 [], 2462 list(a.itersiblings())) 2463 self.assertEqual( 2464 [c], 2465 list(b.itersiblings())) 2466 self.assertEqual( 2467 [], 2468 list(c.itersiblings())) 2469 self.assertEqual( 2470 [b], 2471 list(c.itersiblings(preceding=True))) 2472 self.assertEqual( 2473 [], 2474 list(b.itersiblings(preceding=True)))
2475
2476 - def test_itersiblings_tag(self):
2477 Element = self.etree.Element 2478 SubElement = self.etree.SubElement 2479 2480 a = Element('a') 2481 b = SubElement(a, 'b') 2482 c = SubElement(a, 'c') 2483 d = SubElement(b, 'd') 2484 self.assertEqual( 2485 [], 2486 list(a.itersiblings(tag='XXX'))) 2487 self.assertEqual( 2488 [c], 2489 list(b.itersiblings(tag='c'))) 2490 self.assertEqual( 2491 [c], 2492 list(b.itersiblings(tag='*'))) 2493 self.assertEqual( 2494 [b], 2495 list(c.itersiblings(preceding=True, tag='b'))) 2496 self.assertEqual( 2497 [], 2498 list(c.itersiblings(preceding=True, tag='c')))
2499
2500 - def test_itersiblings_tag_multiple(self):
2501 Element = self.etree.Element 2502 SubElement = self.etree.SubElement 2503 2504 a = Element('a') 2505 b = SubElement(a, 'b') 2506 c = SubElement(a, 'c') 2507 d = SubElement(b, 'd') 2508 e = SubElement(a, 'e') 2509 self.assertEqual( 2510 [], 2511 list(a.itersiblings(tag=('XXX', 'YYY')))) 2512 self.assertEqual( 2513 [c, e], 2514 list(b.itersiblings(tag=('c', 'd', 'e')))) 2515 self.assertEqual( 2516 [b], 2517 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd')))) 2518 self.assertEqual( 2519 [c, b], 2520 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2521
2522 - def test_parseid(self):
2523 parseid = self.etree.parseid 2524 XML = self.etree.XML 2525 xml_text = _bytes(''' 2526 <!DOCTYPE document [ 2527 <!ELEMENT document (h1,p)*> 2528 <!ELEMENT h1 (#PCDATA)> 2529 <!ATTLIST h1 myid ID #REQUIRED> 2530 <!ELEMENT p (#PCDATA)> 2531 <!ATTLIST p someid ID #REQUIRED> 2532 ]> 2533 <document> 2534 <h1 myid="chapter1">...</h1> 2535 <p id="note1" class="note">...</p> 2536 <p>Regular paragraph.</p> 2537 <p xml:id="xmlid">XML:ID paragraph.</p> 2538 <p someid="warn1" class="warning">...</p> 2539 </document> 2540 ''') 2541 2542 tree, dic = parseid(BytesIO(xml_text)) 2543 root = tree.getroot() 2544 root2 = XML(xml_text) 2545 self.assertEqual(self._writeElement(root), 2546 self._writeElement(root2)) 2547 expected = { 2548 "chapter1" : root[0], 2549 "xmlid" : root[3], 2550 "warn1" : root[4] 2551 } 2552 self.assertTrue("chapter1" in dic) 2553 self.assertTrue("warn1" in dic) 2554 self.assertTrue("xmlid" in dic) 2555 self._checkIDDict(dic, expected)
2556
2557 - def test_XMLDTDID(self):
2558 XMLDTDID = self.etree.XMLDTDID 2559 XML = self.etree.XML 2560 xml_text = _bytes(''' 2561 <!DOCTYPE document [ 2562 <!ELEMENT document (h1,p)*> 2563 <!ELEMENT h1 (#PCDATA)> 2564 <!ATTLIST h1 myid ID #REQUIRED> 2565 <!ELEMENT p (#PCDATA)> 2566 <!ATTLIST p someid ID #REQUIRED> 2567 ]> 2568 <document> 2569 <h1 myid="chapter1">...</h1> 2570 <p id="note1" class="note">...</p> 2571 <p>Regular paragraph.</p> 2572 <p xml:id="xmlid">XML:ID paragraph.</p> 2573 <p someid="warn1" class="warning">...</p> 2574 </document> 2575 ''') 2576 2577 root, dic = XMLDTDID(xml_text) 2578 root2 = XML(xml_text) 2579 self.assertEqual(self._writeElement(root), 2580 self._writeElement(root2)) 2581 expected = { 2582 "chapter1" : root[0], 2583 "xmlid" : root[3], 2584 "warn1" : root[4] 2585 } 2586 self.assertTrue("chapter1" in dic) 2587 self.assertTrue("warn1" in dic) 2588 self.assertTrue("xmlid" in dic) 2589 self._checkIDDict(dic, expected)
2590
2591 - def test_XMLDTDID_empty(self):
2592 XMLDTDID = self.etree.XMLDTDID 2593 XML = self.etree.XML 2594 xml_text = _bytes(''' 2595 <document> 2596 <h1 myid="chapter1">...</h1> 2597 <p id="note1" class="note">...</p> 2598 <p>Regular paragraph.</p> 2599 <p someid="warn1" class="warning">...</p> 2600 </document> 2601 ''') 2602 2603 root, dic = XMLDTDID(xml_text) 2604 root2 = XML(xml_text) 2605 self.assertEqual(self._writeElement(root), 2606 self._writeElement(root2)) 2607 expected = {} 2608 self._checkIDDict(dic, expected)
2609
2610 - def test_XMLDTDID_no_id_dict(self):
2611 XMLDTDID = self.etree.XMLDTDID 2612 XML = self.etree.XML 2613 xml_text = _bytes(''' 2614 <!DOCTYPE document [ 2615 <!ELEMENT document (h1,p)*> 2616 <!ELEMENT h1 (#PCDATA)> 2617 <!ATTLIST h1 myid ID #REQUIRED> 2618 <!ELEMENT p (#PCDATA)> 2619 <!ATTLIST p someid ID #REQUIRED> 2620 ]> 2621 <document> 2622 <h1 myid="chapter1">...</h1> 2623 <p id="note1" class="note">...</p> 2624 <p>Regular paragraph.</p> 2625 <p xml:id="xmlid">XML:ID paragraph.</p> 2626 <p someid="warn1" class="warning">...</p> 2627 </document> 2628 ''') 2629 2630 parser = etree.XMLParser(collect_ids=False) 2631 root, dic = XMLDTDID(xml_text, parser=parser) 2632 root2 = XML(xml_text) 2633 self.assertEqual(self._writeElement(root), 2634 self._writeElement(root2)) 2635 self.assertFalse(dic) 2636 self._checkIDDict(dic, {})
2637
2638 - def _checkIDDict(self, dic, expected):
2639 self.assertEqual(len(dic), 2640 len(expected)) 2641 self.assertEqual(sorted(dic.items()), 2642 sorted(expected.items())) 2643 if sys.version_info < (3,): 2644 self.assertEqual(sorted(dic.iteritems()), 2645 sorted(expected.iteritems())) 2646 self.assertEqual(sorted(dic.keys()), 2647 sorted(expected.keys())) 2648 if sys.version_info < (3,): 2649 self.assertEqual(sorted(dic.iterkeys()), 2650 sorted(expected.iterkeys())) 2651 if sys.version_info < (3,): 2652 self.assertEqual(sorted(dic.values()), 2653 sorted(expected.values())) 2654 self.assertEqual(sorted(dic.itervalues()), 2655 sorted(expected.itervalues()))
2656
2657 - def test_register_namespace_xml(self):
2658 self.assertRaises(ValueError, self.etree.register_namespace, 2659 "XML", "http://www.w3.org/XML/1998/namespace") 2660 self.assertRaises(ValueError, self.etree.register_namespace, 2661 "xml", "http://www.w3.org/XML/2345") 2662 self.etree.register_namespace("xml", "http://www.w3.org/XML/1998/namespace") # ok
2663
2664 - def test_namespaces(self):
2665 etree = self.etree 2666 2667 r = {'foo': 'http://ns.infrae.com/foo'} 2668 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2669 self.assertEqual( 2670 'foo', 2671 e.prefix) 2672 self.assertEqual( 2673 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'), 2674 self._writeElement(e))
2675
2676 - def test_namespaces_default(self):
2677 etree = self.etree 2678 2679 r = {None: 'http://ns.infrae.com/foo'} 2680 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2681 self.assertEqual( 2682 None, 2683 e.prefix) 2684 self.assertEqual( 2685 '{http://ns.infrae.com/foo}bar', 2686 e.tag) 2687 self.assertEqual( 2688 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'), 2689 self._writeElement(e))
2690
2691 - def test_namespaces_default_and_other(self):
2692 etree = self.etree 2693 2694 r = {None: 'http://ns.infrae.com/foo', 'p': 'http://test/'} 2695 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2696 self.assertEqual(None, e.prefix) 2697 self.assertEqual('{http://ns.infrae.com/foo}bar', e.tag) 2698 self.assertEqual( 2699 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:p="http://test/"></bar>'), 2700 self._writeElement(e))
2701
2702 - def test_namespaces_default_and_attr(self):
2703 etree = self.etree 2704 2705 r = {None: 'http://ns.infrae.com/foo', 2706 'hoi': 'http://ns.infrae.com/hoi'} 2707 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2708 e.set('{http://ns.infrae.com/hoi}test', 'value') 2709 self.assertEqual( 2710 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'), 2711 self._writeElement(e))
2712
2713 - def test_attribute_keeps_namespace_prefix_on_merge(self):
2714 etree = self.etree 2715 2716 root = etree.Element('{http://test/ns}root', 2717 nsmap={None: 'http://test/ns'}) 2718 sub = etree.Element('{http://test/ns}sub', 2719 nsmap={'test': 'http://test/ns'}) 2720 2721 sub.attrib['{http://test/ns}attr'] = 'value' 2722 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2723 self.assertEqual( 2724 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 2725 etree.tostring(sub)) 2726 2727 root.append(sub) 2728 self.assertEqual( 2729 _bytes('<root xmlns="http://test/ns">' 2730 '<sub xmlns:test="http://test/ns" test:attr="value"/>' 2731 '</root>'), 2732 etree.tostring(root))
2733
2734 - def test_attribute_keeps_namespace_prefix_on_merge_with_nons(self):
2735 etree = self.etree 2736 2737 root = etree.Element('root') 2738 sub = etree.Element('{http://test/ns}sub', 2739 nsmap={'test': 'http://test/ns'}) 2740 2741 sub.attrib['{http://test/ns}attr'] = 'value' 2742 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2743 self.assertEqual( 2744 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 2745 etree.tostring(sub)) 2746 2747 root.append(sub) 2748 self.assertEqual( 2749 _bytes('<root>' 2750 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>' 2751 '</root>'), 2752 etree.tostring(root))
2753
2754 - def test_attribute_gets_namespace_prefix_on_merge_with_nons(self):
2755 etree = self.etree 2756 2757 root = etree.Element('root') 2758 sub = etree.Element('{http://test/ns}sub', 2759 nsmap={None: 'http://test/ns'}) 2760 2761 sub.attrib['{http://test/ns}attr'] = 'value' 2762 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2763 self.assertEqual( 2764 _bytes('<sub xmlns="http://test/ns" ' 2765 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 2766 etree.tostring(sub)) 2767 2768 root.append(sub) 2769 self.assertEqual( 2770 _bytes('<root>' 2771 '<sub xmlns="http://test/ns"' 2772 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>' 2773 '</root>'), 2774 etree.tostring(root))
2775
2776 - def test_attribute_gets_namespace_prefix_on_merge(self):
2777 etree = self.etree 2778 2779 root = etree.Element('{http://test/ns}root', 2780 nsmap={'test': 'http://test/ns', 2781 None: 'http://test/ns'}) 2782 sub = etree.Element('{http://test/ns}sub', 2783 nsmap={None: 'http://test/ns'}) 2784 2785 sub.attrib['{http://test/ns}attr'] = 'value' 2786 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2787 self.assertEqual( 2788 _bytes('<sub xmlns="http://test/ns" ' 2789 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 2790 etree.tostring(sub)) 2791 2792 root.append(sub) 2793 self.assertEqual( 2794 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">' 2795 '<test:sub test:attr="value"/>' 2796 '</test:root>'), 2797 etree.tostring(root))
2798
2799 - def test_namespaces_elementtree(self):
2800 etree = self.etree 2801 r = {None: 'http://ns.infrae.com/foo', 2802 'hoi': 'http://ns.infrae.com/hoi'} 2803 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 2804 tree = etree.ElementTree(element=e) 2805 etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 2806 self.assertEqual( 2807 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'), 2808 self._writeElement(e))
2809
2810 - def test_namespaces_default_copy_element(self):
2811 etree = self.etree 2812 2813 r = {None: 'http://ns.infrae.com/foo'} 2814 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2815 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2816 2817 e1.append(e2) 2818 2819 self.assertEqual( 2820 None, 2821 e1.prefix) 2822 self.assertEqual( 2823 None, 2824 e1[0].prefix) 2825 self.assertEqual( 2826 '{http://ns.infrae.com/foo}bar', 2827 e1.tag) 2828 self.assertEqual( 2829 '{http://ns.infrae.com/foo}bar', 2830 e1[0].tag)
2831
2832 - def test_namespaces_copy_element(self):
2833 etree = self.etree 2834 2835 r = {None: 'http://ns.infrae.com/BAR'} 2836 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 2837 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2838 2839 e1.append(e2) 2840 2841 self.assertEqual( 2842 None, 2843 e1.prefix) 2844 self.assertNotEqual( 2845 None, 2846 e2.prefix) 2847 self.assertEqual( 2848 '{http://ns.infrae.com/BAR}bar', 2849 e1.tag) 2850 self.assertEqual( 2851 '{http://ns.infrae.com/foo}bar', 2852 e2.tag)
2853
2854 - def test_namespaces_reuse_after_move(self):
2855 ns_href = "http://a.b.c" 2856 one = self.etree.fromstring( 2857 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 2858 baz = one[0][0] 2859 2860 two = self.etree.fromstring( 2861 _bytes('<root xmlns:ns="%s"/>' % ns_href)) 2862 two.append(baz) 2863 del one # make sure the source document is deallocated 2864 2865 self.assertEqual('{%s}baz' % ns_href, baz.tag) 2866 self.assertEqual( 2867 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href), 2868 self.etree.tostring(two))
2869
2870 - def test_namespace_cleanup(self):
2871 xml = _bytes( 2872 '<foo xmlns="F" xmlns:x="x">' 2873 '<bar xmlns:ns="NS" xmlns:b="b" xmlns="B">' 2874 '<ns:baz/>' 2875 '</bar></foo>' 2876 ) 2877 root = self.etree.fromstring(xml) 2878 self.assertEqual(xml, self.etree.tostring(root)) 2879 self.etree.cleanup_namespaces(root) 2880 self.assertEqual( 2881 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'), 2882 self.etree.tostring(root))
2883
2884 - def test_namespace_cleanup_attributes(self):
2885 xml = _bytes( 2886 '<foo xmlns="F" xmlns:x="X" xmlns:a="A">' 2887 '<bar xmlns:ns="NS" xmlns:b="b" xmlns="B">' 2888 '<ns:baz a:test="attr"/>' 2889 '</bar></foo>' 2890 ) 2891 root = self.etree.fromstring(xml) 2892 self.assertEqual(xml, self.etree.tostring(root)) 2893 self.etree.cleanup_namespaces(root) 2894 self.assertEqual( 2895 _bytes('<foo xmlns="F" xmlns:a="A">' 2896 '<bar xmlns:ns="NS" xmlns="B">' 2897 '<ns:baz a:test="attr"/>' 2898 '</bar></foo>'), 2899 self.etree.tostring(root))
2900
2901 - def test_namespace_cleanup_many(self):
2902 xml = ('<n12:foo ' + 2903 ' '.join('xmlns:n{n}="NS{n}"'.format(n=i) for i in range(100)) + 2904 '><n68:a/></n12:foo>').encode('utf8') 2905 root = self.etree.fromstring(xml) 2906 self.assertEqual(xml, self.etree.tostring(root)) 2907 self.etree.cleanup_namespaces(root) 2908 self.assertEqual( 2909 b'<n12:foo xmlns:n12="NS12" xmlns:n68="NS68"><n68:a/></n12:foo>', 2910 self.etree.tostring(root))
2911
2912 - def test_namespace_cleanup_deep(self):
2913 xml = ('<root>' + 2914 ''.join('<a xmlns:n{n}="NS{n}">'.format(n=i) for i in range(100)) + 2915 '<n64:x/>' + '</a>'*100 + '</root>').encode('utf8') 2916 root = self.etree.fromstring(xml) 2917 self.assertEqual(xml, self.etree.tostring(root)) 2918 self.etree.cleanup_namespaces(root) 2919 self.assertEqual( 2920 b'<root>' + b'<a>'*64 + b'<a xmlns:n64="NS64">' + b'<a>'*35 + 2921 b'<n64:x/>' + b'</a>'*100 + b'</root>', 2922 self.etree.tostring(root))
2923
2924 - def test_namespace_cleanup_deep_to_top(self):
2925 xml = ('<root>' + 2926 ''.join('<a xmlns:n{n}="NS{n}">'.format(n=i) for i in range(100)) + 2927 '<n64:x xmlns:a="A" a:attr="X"/>' + 2928 '</a>'*100 + 2929 '</root>').encode('utf8') 2930 root = self.etree.fromstring(xml) 2931 self.assertEqual(xml, self.etree.tostring(root)) 2932 self.etree.cleanup_namespaces(root, top_nsmap={'n64': 'NS64'}) 2933 self.assertEqual( 2934 b'<root xmlns:n64="NS64">' + b'<a>'*100 + 2935 b'<n64:x xmlns:a="A" a:attr="X"/>' + b'</a>'*100 + b'</root>', 2936 self.etree.tostring(root))
2937
2938 - def test_namespace_cleanup_keep_prefixes(self):
2939 xml = ('<root xmlns:n64="NS64" xmlns:foo="FOO" xmlns:unused1="UNUSED" xmlns:no="NO">' 2940 '<a xmlns:unused2="UNUSED"><n64:x xmlns:a="A" a:attr="X"/></a>' 2941 '<foo>foo:bar</foo>' 2942 '</root>').encode('utf8') 2943 root = self.etree.fromstring(xml) 2944 self.assertEqual(xml, self.etree.tostring(root)) 2945 self.etree.cleanup_namespaces(root, keep_ns_prefixes=['foo']) 2946 self.assertEqual( 2947 b'<root xmlns:n64="NS64" xmlns:foo="FOO">' 2948 b'<a><n64:x xmlns:a="A" a:attr="X"/></a>' 2949 b'<foo>foo:bar</foo>' 2950 b'</root>', 2951 self.etree.tostring(root))
2952
2953 - def test_namespace_cleanup_keep_prefixes_top(self):
2954 xml = ('<root xmlns:n64="NS64" xmlns:unused1="UNUSED" xmlns:no="NO">' 2955 '<sub xmlns:foo="FOO">' 2956 '<a xmlns:unused2="UNUSED"><n64:x xmlns:a="A" a:attr="X"/></a>' 2957 '<foo>foo:bar</foo>' 2958 '</sub>' 2959 '</root>').encode('utf8') 2960 root = self.etree.fromstring(xml) 2961 self.assertEqual(xml, self.etree.tostring(root)) 2962 self.etree.cleanup_namespaces( 2963 root, 2964 top_nsmap={'foo': 'FOO', 'unused1': 'UNUSED'}, 2965 keep_ns_prefixes=['foo']) 2966 self.assertEqual( 2967 b'<root xmlns:n64="NS64" xmlns:foo="FOO">' 2968 b'<sub>' 2969 b'<a><n64:x xmlns:a="A" a:attr="X"/></a>' 2970 b'<foo>foo:bar</foo>' 2971 b'</sub>' 2972 b'</root>', 2973 self.etree.tostring(root))
2974
2975 - def test_element_nsmap(self):
2976 etree = self.etree 2977 2978 r = {None: 'http://ns.infrae.com/foo', 2979 'hoi': 'http://ns.infrae.com/hoi'} 2980 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2981 self.assertEqual( 2982 r, 2983 e.nsmap)
2984
2985 - def test_subelement_nsmap(self):
2986 etree = self.etree 2987 2988 re = {None: 'http://ns.infrae.com/foo', 2989 'hoi': 'http://ns.infrae.com/hoi'} 2990 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re) 2991 2992 rs = {None: 'http://ns.infrae.com/honk', 2993 'top': 'http://ns.infrae.com/top'} 2994 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs) 2995 2996 r = re.copy() 2997 r.update(rs) 2998 self.assertEqual(re, e.nsmap) 2999 self.assertEqual(r, s.nsmap)
3000
3001 - def test_html_prefix_nsmap(self):
3002 etree = self.etree 3003 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description') 3004 self.assertEqual({'hha': None}, el.nsmap)
3005
3006 - def test_getiterator_filter_multiple(self):
3007 Element = self.etree.Element 3008 SubElement = self.etree.SubElement 3009 3010 a = Element('a') 3011 b = SubElement(a, 'b') 3012 c = SubElement(a, 'c') 3013 d = SubElement(b, 'd') 3014 e = SubElement(c, 'e') 3015 f = SubElement(c, 'f') 3016 3017 self.assertEqual( 3018 [a, b], 3019 list(a.getiterator('a', 'b'))) 3020 self.assertEqual( 3021 [], 3022 list(a.getiterator('x', 'y'))) 3023 self.assertEqual( 3024 [a, f], 3025 list(a.getiterator('f', 'a'))) 3026 self.assertEqual( 3027 [c, e, f], 3028 list(c.getiterator('c', '*', 'a'))) 3029 self.assertEqual( 3030 [], 3031 list(a.getiterator( (), () )))
3032
3033 - def test_getiterator_filter_multiple_tuple(self):
3034 Element = self.etree.Element 3035 SubElement = self.etree.SubElement 3036 3037 a = Element('a') 3038 b = SubElement(a, 'b') 3039 c = SubElement(a, 'c') 3040 d = SubElement(b, 'd') 3041 e = SubElement(c, 'e') 3042 f = SubElement(c, 'f') 3043 3044 self.assertEqual( 3045 [a, b], 3046 list(a.getiterator( ('a', 'b') ))) 3047 self.assertEqual( 3048 [], 3049 list(a.getiterator( ('x', 'y') ))) 3050 self.assertEqual( 3051 [a, f], 3052 list(a.getiterator( ('f', 'a') ))) 3053 self.assertEqual( 3054 [c, e, f], 3055 list(c.getiterator( ('c', '*', 'a') ))) 3056 self.assertEqual( 3057 [], 3058 list(a.getiterator( () )))
3059
3060 - def test_getiterator_filter_namespace(self):
3061 Element = self.etree.Element 3062 SubElement = self.etree.SubElement 3063 3064 a = Element('{a}a') 3065 b = SubElement(a, '{a}b') 3066 c = SubElement(a, '{a}c') 3067 d = SubElement(b, '{b}d') 3068 e = SubElement(c, '{a}e') 3069 f = SubElement(c, '{b}f') 3070 g = SubElement(c, 'g') 3071 3072 self.assertEqual( 3073 [a], 3074 list(a.getiterator('{a}a'))) 3075 self.assertEqual( 3076 [], 3077 list(a.getiterator('{b}a'))) 3078 self.assertEqual( 3079 [], 3080 list(a.getiterator('a'))) 3081 self.assertEqual( 3082 [a,b,d,c,e,f,g], 3083 list(a.getiterator('*'))) 3084 self.assertEqual( 3085 [f], 3086 list(c.getiterator('{b}*'))) 3087 self.assertEqual( 3088 [d, f], 3089 list(a.getiterator('{b}*'))) 3090 self.assertEqual( 3091 [g], 3092 list(a.getiterator('g'))) 3093 self.assertEqual( 3094 [g], 3095 list(a.getiterator('{}g'))) 3096 self.assertEqual( 3097 [g], 3098 list(a.getiterator('{}*')))
3099
3100 - def test_getiterator_filter_local_name(self):
3101 Element = self.etree.Element 3102 Comment = self.etree.Comment 3103 SubElement = self.etree.SubElement 3104 3105 a = Element('{a}a') 3106 b = SubElement(a, '{nsA}b') 3107 c = SubElement(b, '{nsB}b') 3108 d = SubElement(a, 'b') 3109 e = SubElement(a, '{nsA}e') 3110 f = SubElement(e, '{nsB}e') 3111 g = SubElement(e, 'e') 3112 a.append(Comment('test')) 3113 3114 self.assertEqual( 3115 [b, c, d], 3116 list(a.getiterator('{*}b'))) 3117 self.assertEqual( 3118 [e, f, g], 3119 list(a.getiterator('{*}e'))) 3120 self.assertEqual( 3121 [a, b, c, d, e, f, g], 3122 list(a.getiterator('{*}*')))
3123
3124 - def test_getiterator_filter_entities(self):
3125 Element = self.etree.Element 3126 Entity = self.etree.Entity 3127 SubElement = self.etree.SubElement 3128 3129 a = Element('a') 3130 b = SubElement(a, 'b') 3131 entity_b = Entity("TEST-b") 3132 b.append(entity_b) 3133 3134 self.assertEqual( 3135 [entity_b], 3136 list(a.getiterator(Entity))) 3137 3138 entity_a = Entity("TEST-a") 3139 a.append(entity_a) 3140 3141 self.assertEqual( 3142 [entity_b, entity_a], 3143 list(a.getiterator(Entity))) 3144 3145 self.assertEqual( 3146 [entity_b], 3147 list(b.getiterator(Entity)))
3148
3149 - def test_getiterator_filter_element(self):
3150 Element = self.etree.Element 3151 Comment = self.etree.Comment 3152 PI = self.etree.PI 3153 SubElement = self.etree.SubElement 3154 3155 a = Element('a') 3156 b = SubElement(a, 'b') 3157 a.append(Comment("test")) 3158 a.append(PI("pi", "content")) 3159 c = SubElement(a, 'c') 3160 3161 self.assertEqual( 3162 [a, b, c], 3163 list(a.getiterator(Element)))
3164
3165 - def test_getiterator_filter_all_comment_pi(self):
3166 # ElementTree iterates over everything here 3167 Element = self.etree.Element 3168 Comment = self.etree.Comment 3169 PI = self.etree.PI 3170 SubElement = self.etree.SubElement 3171 3172 a = Element('a') 3173 b = SubElement(a, 'b') 3174 a.append(Comment("test")) 3175 a.append(PI("pi", "content")) 3176 c = SubElement(a, 'c') 3177 3178 self.assertEqual( 3179 [a, b, c], 3180 list(a.getiterator('*')))
3181
3182 - def test_elementtree_getelementpath(self):
3183 a = etree.Element("a") 3184 b = etree.SubElement(a, "b") 3185 c = etree.SubElement(a, "c") 3186 d1 = etree.SubElement(c, "d") 3187 d2 = etree.SubElement(c, "d") 3188 c.text = d1.text = 'TEXT' 3189 3190 tree = etree.ElementTree(a) 3191 self.assertEqual('.', tree.getelementpath(a)) 3192 self.assertEqual('c/d[1]', tree.getelementpath(d1)) 3193 self.assertEqual('c/d[2]', tree.getelementpath(d2)) 3194 3195 self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 3196 self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 3197 3198 tree = etree.ElementTree(c) 3199 self.assertEqual('.', tree.getelementpath(c)) 3200 self.assertEqual('d[2]', tree.getelementpath(d2)) 3201 self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 3202 3203 tree = etree.ElementTree(b) # not a parent of a/c/d1/d2 3204 self.assertEqual('.', tree.getelementpath(b)) 3205 self.assertRaises(ValueError, tree.getelementpath, a) 3206 self.assertRaises(ValueError, tree.getelementpath, c) 3207 self.assertRaises(ValueError, tree.getelementpath, d2)
3208
3209 - def test_elementtree_getelementpath_ns(self):
3210 a = etree.Element("{http://ns1/}a") 3211 b = etree.SubElement(a, "{http://ns1/}b") 3212 c = etree.SubElement(a, "{http://ns1/}c") 3213 d1 = etree.SubElement(c, "{http://ns1/}d") 3214 d2 = etree.SubElement(c, "{http://ns2/}d") 3215 d3 = etree.SubElement(c, "{http://ns1/}d") 3216 3217 tree = etree.ElementTree(a) 3218 self.assertEqual('.', tree.getelementpath(a)) 3219 self.assertEqual('{http://ns1/}c/{http://ns1/}d[1]', 3220 tree.getelementpath(d1)) 3221 self.assertEqual('{http://ns1/}c/{http://ns2/}d', 3222 tree.getelementpath(d2)) 3223 self.assertEqual('{http://ns1/}c/{http://ns1/}d[2]', 3224 tree.getelementpath(d3)) 3225 3226 self.assertEqual(a, tree.find(tree.getelementpath(a))) 3227 self.assertEqual(b, tree.find(tree.getelementpath(b))) 3228 self.assertEqual(c, tree.find(tree.getelementpath(c))) 3229 self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 3230 self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 3231 self.assertEqual(d3, tree.find(tree.getelementpath(d3))) 3232 3233 tree = etree.ElementTree(c) 3234 self.assertEqual('{http://ns1/}d[1]', tree.getelementpath(d1)) 3235 self.assertEqual('{http://ns2/}d', tree.getelementpath(d2)) 3236 self.assertEqual('{http://ns1/}d[2]', tree.getelementpath(d3)) 3237 self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 3238 self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 3239 self.assertEqual(d3, tree.find(tree.getelementpath(d3))) 3240 3241 tree = etree.ElementTree(b) # not a parent of d1/d2 3242 self.assertRaises(ValueError, tree.getelementpath, d1) 3243 self.assertRaises(ValueError, tree.getelementpath, d2)
3244
3245 - def test_elementtree_find_qname(self):
3246 XML = self.etree.XML 3247 ElementTree = self.etree.ElementTree 3248 QName = self.etree.QName 3249 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 3250 self.assertEqual(tree.find(QName("c")), tree.getroot()[2])
3251
3252 - def test_elementtree_findall_qname(self):
3253 XML = self.etree.XML 3254 ElementTree = self.etree.ElementTree 3255 QName = self.etree.QName 3256 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 3257 self.assertEqual(len(list(tree.findall(QName("c")))), 1)
3258
3259 - def test_elementtree_findall_ns_qname(self):
3260 XML = self.etree.XML 3261 ElementTree = self.etree.ElementTree 3262 QName = self.etree.QName 3263 tree = ElementTree(XML( 3264 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))) 3265 self.assertEqual(len(list(tree.findall(QName("b")))), 2) 3266 self.assertEqual(len(list(tree.findall(QName("X", "b")))), 1)
3267
3268 - def test_findall_ns(self):
3269 XML = self.etree.XML 3270 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')) 3271 self.assertEqual(len(root.findall(".//{X}b")), 2) 3272 self.assertEqual(len(root.findall(".//{X}*")), 2) 3273 self.assertEqual(len(root.findall(".//b")), 3)
3274
3275 - def test_findall_different_nsmaps(self):
3276 XML = self.etree.XML 3277 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>')) 3278 nsmap = {'xx': 'X'} 3279 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) 3280 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2) 3281 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2) 3282 nsmap = {'xx': 'Y'} 3283 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1) 3284 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1) 3285 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
3286
3287 - def test_findall_empty_prefix(self):
3288 XML = self.etree.XML 3289 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>')) 3290 nsmap = {'xx': 'X'} 3291 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) 3292 nsmap = {'xx': 'X', None: 'Y'} 3293 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 1) 3294 nsmap = {'xx': 'X', '': 'Y'} 3295 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 1)
3296
3297 - def test_findall_syntax_error(self):
3298 XML = self.etree.XML 3299 root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>')) 3300 self.assertRaises(SyntaxError, root.findall, '') 3301 self.assertRaises(SyntaxError, root.findall, '//') # absolute path on Element 3302 self.assertRaises(SyntaxError, root.findall, './//')
3303
3304 - def test_index(self):
3305 etree = self.etree 3306 e = etree.Element('foo') 3307 for i in range(10): 3308 etree.SubElement(e, 'a%s' % i) 3309 for i in range(10): 3310 self.assertEqual( 3311 i, 3312 e.index(e[i])) 3313 self.assertEqual( 3314 3, e.index(e[3], 3)) 3315 self.assertRaises( 3316 ValueError, e.index, e[3], 4) 3317 self.assertRaises( 3318 ValueError, e.index, e[3], 0, 2) 3319 self.assertRaises( 3320 ValueError, e.index, e[8], 0, -3) 3321 self.assertRaises( 3322 ValueError, e.index, e[8], -5, -3) 3323 self.assertEqual( 3324 8, e.index(e[8], 0, -1)) 3325 self.assertEqual( 3326 8, e.index(e[8], -12, -1)) 3327 self.assertEqual( 3328 0, e.index(e[0], -12, -1))
3329
3330 - def test_replace(self):
3331 etree = self.etree 3332 e = etree.Element('foo') 3333 for i in range(10): 3334 el = etree.SubElement(e, 'a%s' % i) 3335 el.text = "text%d" % i 3336 el.tail = "tail%d" % i 3337 3338 child0 = e[0] 3339 child1 = e[1] 3340 child2 = e[2] 3341 3342 e.replace(e[0], e[1]) 3343 self.assertEqual( 3344 9, len(e)) 3345 self.assertEqual( 3346 child1, e[0]) 3347 self.assertEqual( 3348 child1.text, "text1") 3349 self.assertEqual( 3350 child1.tail, "tail1") 3351 self.assertEqual( 3352 child0.tail, "tail0") 3353 self.assertEqual( 3354 child2, e[1]) 3355 3356 e.replace(e[-1], e[0]) 3357 self.assertEqual( 3358 child1, e[-1]) 3359 self.assertEqual( 3360 child1.text, "text1") 3361 self.assertEqual( 3362 child1.tail, "tail1") 3363 self.assertEqual( 3364 child2, e[0])
3365
3366 - def test_replace_new(self):
3367 etree = self.etree 3368 e = etree.Element('foo') 3369 for i in range(10): 3370 etree.SubElement(e, 'a%s' % i) 3371 3372 new_element = etree.Element("test") 3373 new_element.text = "TESTTEXT" 3374 new_element.tail = "TESTTAIL" 3375 child1 = e[1] 3376 e.replace(e[0], new_element) 3377 self.assertEqual( 3378 new_element, e[0]) 3379 self.assertEqual( 3380 "TESTTEXT", 3381 e[0].text) 3382 self.assertEqual( 3383 "TESTTAIL", 3384 e[0].tail) 3385 self.assertEqual( 3386 child1, e[1])
3387
3388 - def test_setslice_all_reversed(self):
3389 Element = self.etree.Element 3390 SubElement = self.etree.SubElement 3391 3392 a = Element('a') 3393 3394 e = Element('e') 3395 f = Element('f') 3396 g = Element('g') 3397 3398 a[:] = [e, f, g] 3399 self.assertEqual( 3400 [e, f, g], 3401 list(a)) 3402 3403 a[::-1] = [e, f, g] 3404 self.assertEqual( 3405 [g, f, e], 3406 list(a))
3407
3408 - def test_setslice_step(self):
3409 Element = self.etree.Element 3410 SubElement = self.etree.SubElement 3411 3412 a = Element('a') 3413 b = SubElement(a, 'b') 3414 c = SubElement(a, 'c') 3415 d = SubElement(a, 'd') 3416 e = SubElement(a, 'e') 3417 3418 x = Element('x') 3419 y = Element('y') 3420 3421 a[1::2] = [x, y] 3422 self.assertEqual( 3423 [b, x, d, y], 3424 list(a))
3425
3426 - def test_setslice_step_negative(self):
3427 Element = self.etree.Element 3428 SubElement = self.etree.SubElement 3429 3430 a = Element('a') 3431 b = SubElement(a, 'b') 3432 c = SubElement(a, 'c') 3433 d = SubElement(a, 'd') 3434 e = SubElement(a, 'e') 3435 3436 x = Element('x') 3437 y = Element('y') 3438 3439 a[1::-1] = [x, y] 3440 self.assertEqual( 3441 [y, x, d, e], 3442 list(a))
3443
3444 - def test_setslice_step_negative2(self):
3445 Element = self.etree.Element 3446 SubElement = self.etree.SubElement 3447 3448 a = Element('a') 3449 b = SubElement(a, 'b') 3450 c = SubElement(a, 'c') 3451 d = SubElement(a, 'd') 3452 e = SubElement(a, 'e') 3453 3454 x = Element('x') 3455 y = Element('y') 3456 3457 a[::-2] = [x, y] 3458 self.assertEqual( 3459 [b, y, d, x], 3460 list(a))
3461
3462 - def test_setslice_step_overrun(self):
3463 Element = self.etree.Element 3464 SubElement = self.etree.SubElement 3465 try: 3466 slice 3467 except NameError: 3468 print("slice() not found") 3469 return 3470 3471 a = Element('a') 3472 b = SubElement(a, 'b') 3473 c = SubElement(a, 'c') 3474 d = SubElement(a, 'd') 3475 e = SubElement(a, 'e') 3476 3477 x = Element('x') 3478 y = Element('y') 3479 z = Element('z') 3480 3481 self.assertRaises( 3482 ValueError, 3483 operator.setitem, a, slice(1,None,2), [x, y, z]) 3484 3485 self.assertEqual( 3486 [b, c, d, e], 3487 list(a))
3488
3489 - def test_sourceline_XML(self):
3490 XML = self.etree.XML 3491 root = XML(_bytes('''<?xml version="1.0"?> 3492 <root><test> 3493 3494 <bla/></test> 3495 </root> 3496 ''')) 3497 3498 self.assertEqual( 3499 [2, 2, 4], 3500 [ el.sourceline for el in root.getiterator() ])
3501
3502 - def test_large_sourceline_XML(self):
3503 XML = self.etree.XML 3504 root = XML(_bytes( 3505 '<?xml version="1.0"?>\n' 3506 '<root>' + '\n' * 65536 + 3507 '<p>' + '\n' * 65536 + '</p>\n' + 3508 '<br/>\n' 3509 '</root>')) 3510 3511 if self.etree.LIBXML_VERSION >= (2, 9): 3512 expected = [2, 131074, 131076] 3513 else: 3514 expected = [2, 65535, 65535] 3515 3516 self.assertEqual(expected, [el.sourceline for el in root.iter()])
3517
3518 - def test_sourceline_parse(self):
3519 parse = self.etree.parse 3520 tree = parse(fileInTestDir('include/test_xinclude.xml')) 3521 3522 self.assertEqual( 3523 [1, 2, 3], 3524 [ el.sourceline for el in tree.getiterator() ])
3525
3526 - def test_sourceline_iterparse_end(self):
3527 iterparse = self.etree.iterparse 3528 lines = [ el.sourceline for (event, el) in 3529 iterparse(fileInTestDir('include/test_xinclude.xml')) ] 3530 3531 self.assertEqual( 3532 [2, 3, 1], 3533 lines)
3534
3535 - def test_sourceline_iterparse_start(self):
3536 iterparse = self.etree.iterparse 3537 lines = [ el.sourceline for (event, el) in 3538 iterparse(fileInTestDir('include/test_xinclude.xml'), 3539 events=("start",)) ] 3540 3541 self.assertEqual( 3542 [1, 2, 3], 3543 lines)
3544
3545 - def test_sourceline_element(self):
3546 Element = self.etree.Element 3547 SubElement = self.etree.SubElement 3548 el = Element("test") 3549 self.assertEqual(None, el.sourceline) 3550 3551 child = SubElement(el, "test") 3552 self.assertEqual(None, el.sourceline) 3553 self.assertEqual(None, child.sourceline)
3554
3555 - def test_XML_base_url_docinfo(self):
3556 etree = self.etree 3557 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3558 docinfo = root.getroottree().docinfo 3559 self.assertEqual(docinfo.URL, "http://no/such/url")
3560
3561 - def test_XML_set_base_url_docinfo(self):
3562 etree = self.etree 3563 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3564 docinfo = root.getroottree().docinfo 3565 self.assertEqual(docinfo.URL, "http://no/such/url") 3566 docinfo.URL = "https://secret/url" 3567 self.assertEqual(docinfo.URL, "https://secret/url")
3568
3569 - def test_parse_stringio_base_url(self):
3570 etree = self.etree 3571 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url") 3572 docinfo = tree.docinfo 3573 self.assertEqual(docinfo.URL, "http://no/such/url")
3574
3575 - def test_parse_base_url_docinfo(self):
3576 etree = self.etree 3577 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 3578 base_url="http://no/such/url") 3579 docinfo = tree.docinfo 3580 self.assertEqual(docinfo.URL, "http://no/such/url")
3581
3582 - def test_HTML_base_url_docinfo(self):
3583 etree = self.etree 3584 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url") 3585 docinfo = root.getroottree().docinfo 3586 self.assertEqual(docinfo.URL, "http://no/such/url")
3587
3588 - def test_docinfo_public(self):
3589 etree = self.etree 3590 xml_header = '<?xml version="1.0" encoding="ascii"?>' 3591 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 3592 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 3593 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id) 3594 3595 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 3596 3597 tree = etree.parse(BytesIO(xml)) 3598 docinfo = tree.docinfo 3599 self.assertEqual(docinfo.encoding, "ascii") 3600 self.assertEqual(docinfo.xml_version, "1.0") 3601 self.assertEqual(docinfo.public_id, pub_id) 3602 self.assertEqual(docinfo.system_url, sys_id) 3603 self.assertEqual(docinfo.root_name, 'html') 3604 self.assertEqual(docinfo.doctype, doctype_string)
3605
3606 - def test_docinfo_system(self):
3607 etree = self.etree 3608 xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 3609 sys_id = "some.dtd" 3610 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 3611 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 3612 3613 tree = etree.parse(BytesIO(xml)) 3614 docinfo = tree.docinfo 3615 self.assertEqual(docinfo.encoding, "UTF-8") 3616 self.assertEqual(docinfo.xml_version, "1.0") 3617 self.assertEqual(docinfo.public_id, None) 3618 self.assertEqual(docinfo.system_url, sys_id) 3619 self.assertEqual(docinfo.root_name, 'html') 3620 self.assertEqual(docinfo.doctype, doctype_string)
3621
3622 - def test_docinfo_empty(self):
3623 etree = self.etree 3624 xml = _bytes('<html><body></body></html>') 3625 tree = etree.parse(BytesIO(xml)) 3626 docinfo = tree.docinfo 3627 self.assertEqual(docinfo.encoding, "UTF-8") 3628 self.assertEqual(docinfo.xml_version, "1.0") 3629 self.assertEqual(docinfo.public_id, None) 3630 self.assertEqual(docinfo.system_url, None) 3631 self.assertEqual(docinfo.root_name, 'html') 3632 self.assertEqual(docinfo.doctype, '')
3633
3634 - def test_docinfo_name_only(self):
3635 etree = self.etree 3636 xml = _bytes('<!DOCTYPE root><root></root>') 3637 tree = etree.parse(BytesIO(xml)) 3638 docinfo = tree.docinfo 3639 self.assertEqual(docinfo.encoding, "UTF-8") 3640 self.assertEqual(docinfo.xml_version, "1.0") 3641 self.assertEqual(docinfo.public_id, None) 3642 self.assertEqual(docinfo.system_url, None) 3643 self.assertEqual(docinfo.root_name, 'root') 3644 self.assertEqual(docinfo.doctype, '<!DOCTYPE root>')
3645
3646 - def test_doctype_name_only_roundtrip(self):
3647 etree = self.etree 3648 xml = _bytes('<!DOCTYPE root>\n<root/>') 3649 tree = etree.parse(BytesIO(xml)) 3650 self.assertEqual(xml, etree.tostring(tree))
3651
3652 - def test_doctype_output_override(self):
3653 etree = self.etree 3654 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 3655 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 3656 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)) 3657 3658 xml = _bytes('<!DOCTYPE root>\n<root/>') 3659 tree = etree.parse(BytesIO(xml)) 3660 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string), 3661 etree.tostring(tree, doctype=doctype_string))
3662
3663 - def test_xml_base(self):
3664 etree = self.etree 3665 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3666 self.assertEqual(root.base, "http://no/such/url") 3667 self.assertEqual( 3668 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 3669 root.base = "https://secret/url" 3670 self.assertEqual(root.base, "https://secret/url") 3671 self.assertEqual( 3672 root.get('{http://www.w3.org/XML/1998/namespace}base'), 3673 "https://secret/url")
3674
3675 - def test_xml_base_attribute(self):
3676 etree = self.etree 3677 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3678 self.assertEqual(root.base, "http://no/such/url") 3679 self.assertEqual( 3680 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 3681 root.set('{http://www.w3.org/XML/1998/namespace}base', 3682 "https://secret/url") 3683 self.assertEqual(root.base, "https://secret/url") 3684 self.assertEqual( 3685 root.get('{http://www.w3.org/XML/1998/namespace}base'), 3686 "https://secret/url")
3687
3688 - def test_html_base(self):
3689 etree = self.etree 3690 root = etree.HTML(_bytes("<html><body></body></html>"), 3691 base_url="http://no/such/url") 3692 self.assertEqual(root.base, "http://no/such/url")
3693
3694 - def test_html_base_tag(self):
3695 etree = self.etree 3696 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>')) 3697 self.assertEqual(root.base, "http://no/such/url")
3698
3699 - def test_parse_fileobject_unicode(self):
3700 # parse from a file object that returns unicode strings 3701 f = LargeFileLikeUnicode() 3702 tree = self.etree.parse(f) 3703 root = tree.getroot() 3704 self.assertTrue(root.tag.endswith('root'))
3705
3706 - def test_dtd_io(self):
3707 # check that DTDs that go in also go back out 3708 xml = _bytes('''\ 3709 <!DOCTYPE test SYSTEM "test.dtd" [ 3710 <!ENTITY entity "tasty"> 3711 <!ELEMENT test (a)> 3712 <!ELEMENT a (#PCDATA)> 3713 ]> 3714 <test><a>test-test</a></test>\ 3715 ''') 3716 tree = self.etree.parse(BytesIO(xml)) 3717 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")), 3718 xml.replace(_bytes(" "), _bytes("")))
3719
3720 - def test_byte_zero(self):
3721 Element = self.etree.Element 3722 3723 a = Element('a') 3724 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho') 3725 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho') 3726 3727 self.assertRaises(ValueError, Element, 'ha\0ho')
3728
3729 - def test_unicode_byte_zero(self):
3730 Element = self.etree.Element 3731 3732 a = Element('a') 3733 self.assertRaises(ValueError, setattr, a, "text", 3734 _str('ha\0ho')) 3735 self.assertRaises(ValueError, setattr, a, "tail", 3736 _str('ha\0ho')) 3737 3738 self.assertRaises(ValueError, Element, 3739 _str('ha\0ho'))
3740
3741 - def test_byte_invalid(self):
3742 Element = self.etree.Element 3743 3744 a = Element('a') 3745 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho') 3746 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho') 3747 3748 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho') 3749 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho') 3750 3751 self.assertRaises(ValueError, Element, 'ha\x07ho') 3752 self.assertRaises(ValueError, Element, 'ha\x02ho')
3753
3754 - def test_unicode_byte_invalid(self):
3755 Element = self.etree.Element 3756 3757 a = Element('a') 3758 self.assertRaises(ValueError, setattr, a, "text", 3759 _str('ha\x07ho')) 3760 self.assertRaises(ValueError, setattr, a, "text", 3761 _str('ha\x02ho')) 3762 3763 self.assertRaises(ValueError, setattr, a, "tail", 3764 _str('ha\x07ho')) 3765 self.assertRaises(ValueError, setattr, a, "tail", 3766 _str('ha\x02ho')) 3767 3768 self.assertRaises(ValueError, Element, 3769 _str('ha\x07ho')) 3770 self.assertRaises(ValueError, Element, 3771 _str('ha\x02ho'))
3772
3773 - def test_unicode_byte_invalid_sequence(self):
3774 Element = self.etree.Element 3775 3776 a = Element('a') 3777 self.assertRaises(ValueError, setattr, a, "text", 3778 _str('ha\u1234\x07ho')) 3779 self.assertRaises(ValueError, setattr, a, "text", 3780 _str('ha\u1234\x02ho')) 3781 3782 self.assertRaises(ValueError, setattr, a, "tail", 3783 _str('ha\u1234\x07ho')) 3784 self.assertRaises(ValueError, setattr, a, "tail", 3785 _str('ha\u1234\x02ho')) 3786 3787 self.assertRaises(ValueError, Element, 3788 _str('ha\u1234\x07ho')) 3789 self.assertRaises(ValueError, Element, 3790 _str('ha\u1234\x02ho'))
3791
3792 - def test_encoding_tostring_utf16(self):
3793 # ElementTree fails to serialize this 3794 tostring = self.etree.tostring 3795 Element = self.etree.Element 3796 SubElement = self.etree.SubElement 3797 3798 a = Element('a') 3799 b = SubElement(a, 'b') 3800 c = SubElement(a, 'c') 3801 3802 result = tostring(a, encoding='UTF-16') 3803 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 3804 canonicalize(result))
3805
3806 - def test_tostring_none(self):
3807 # ElementTree raises an AssertionError here 3808 tostring = self.etree.tostring 3809 self.assertRaises(TypeError, self.etree.tostring, None)
3810
3811 - def test_tostring_pretty(self):
3812 tostring = self.etree.tostring 3813 Element = self.etree.Element 3814 SubElement = self.etree.SubElement 3815 3816 a = Element('a') 3817 b = SubElement(a, 'b') 3818 c = SubElement(a, 'c') 3819 3820 result = tostring(a) 3821 self.assertEqual(result, _bytes("<a><b/><c/></a>")) 3822 3823 result = tostring(a, pretty_print=False) 3824 self.assertEqual(result, _bytes("<a><b/><c/></a>")) 3825 3826 result = tostring(a, pretty_print=True) 3827 self.assertEqual(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
3828
3829 - def test_tostring_with_tail(self):
3830 tostring = self.etree.tostring 3831 Element = self.etree.Element 3832 SubElement = self.etree.SubElement 3833 3834 a = Element('a') 3835 a.tail = "aTAIL" 3836 b = SubElement(a, 'b') 3837 b.tail = "bTAIL" 3838 c = SubElement(a, 'c') 3839 3840 result = tostring(a) 3841 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL")) 3842 3843 result = tostring(a, with_tail=False) 3844 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>")) 3845 3846 result = tostring(a, with_tail=True) 3847 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3848
3849 - def test_tostring_method_html_with_tail(self):
3850 tostring = self.etree.tostring 3851 html = self.etree.fromstring( 3852 '<html><body>' 3853 '<div><p>Some text<i>\r\n</i></p></div>\r\n' 3854 '</body></html>', 3855 parser=self.etree.HTMLParser()) 3856 self.assertEqual(html.tag, 'html') 3857 div = html.find('.//div') 3858 self.assertEqual(div.tail, '\r\n') 3859 result = tostring(div, method='html') 3860 self.assertEqual( 3861 result, 3862 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n")) 3863 result = tostring(div, method='html', with_tail=True) 3864 self.assertEqual( 3865 result, 3866 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n")) 3867 result = tostring(div, method='html', with_tail=False) 3868 self.assertEqual( 3869 result, 3870 _bytes("<div><p>Some text<i>\r\n</i></p></div>"))
3871
3872 - def test_standalone(self):
3873 tostring = self.etree.tostring 3874 XML = self.etree.XML 3875 ElementTree = self.etree.ElementTree 3876 Element = self.etree.Element 3877 3878 tree = Element("root").getroottree() 3879 self.assertEqual(None, tree.docinfo.standalone) 3880 3881 tree = XML(_bytes("<root/>")).getroottree() 3882 self.assertEqual(None, tree.docinfo.standalone) 3883 3884 tree = XML(_bytes( 3885 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>" 3886 )).getroottree() 3887 self.assertEqual(True, tree.docinfo.standalone) 3888 3889 tree = XML(_bytes( 3890 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>" 3891 )).getroottree() 3892 self.assertEqual(False, tree.docinfo.standalone)
3893
3894 - def test_tostring_standalone(self):
3895 tostring = self.etree.tostring 3896 XML = self.etree.XML 3897 ElementTree = self.etree.ElementTree 3898 3899 root = XML(_bytes("<root/>")) 3900 3901 tree = ElementTree(root) 3902 self.assertEqual(None, tree.docinfo.standalone) 3903 3904 result = tostring(root, xml_declaration=True, encoding="ASCII") 3905 self.assertEqual(result, _bytes( 3906 "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 3907 3908 result = tostring(root, xml_declaration=True, encoding="ASCII", 3909 standalone=True) 3910 self.assertEqual(result, _bytes( 3911 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>")) 3912 3913 tree = ElementTree(XML(result)) 3914 self.assertEqual(True, tree.docinfo.standalone) 3915 3916 result = tostring(root, xml_declaration=True, encoding="ASCII", 3917 standalone=False) 3918 self.assertEqual(result, _bytes( 3919 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>")) 3920 3921 tree = ElementTree(XML(result)) 3922 self.assertEqual(False, tree.docinfo.standalone)
3923
3924 - def test_tostring_standalone_in_out(self):
3925 tostring = self.etree.tostring 3926 XML = self.etree.XML 3927 ElementTree = self.etree.ElementTree 3928 3929 root = XML(_bytes( 3930 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>")) 3931 3932 tree = ElementTree(root) 3933 self.assertEqual(True, tree.docinfo.standalone) 3934 3935 result = tostring(root, xml_declaration=True, encoding="ASCII") 3936 self.assertEqual(result, _bytes( 3937 "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 3938 3939 result = tostring(root, xml_declaration=True, encoding="ASCII", 3940 standalone=True) 3941 self.assertEqual(result, _bytes( 3942 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3943
3944 - def test_tostring_method_text_encoding(self):
3945 tostring = self.etree.tostring 3946 Element = self.etree.Element 3947 SubElement = self.etree.SubElement 3948 3949 a = Element('a') 3950 a.text = "A" 3951 a.tail = "tail" 3952 b = SubElement(a, 'b') 3953 b.text = "B" 3954 b.tail = _str("Søk på nettet") 3955 c = SubElement(a, 'c') 3956 c.text = "C" 3957 3958 result = tostring(a, method="text", encoding="UTF-16") 3959 3960 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"), 3961 result)
3962
3963 - def test_tostring_method_text_unicode(self):
3964 tostring = self.etree.tostring 3965 Element = self.etree.Element 3966 SubElement = self.etree.SubElement 3967 3968 a = Element('a') 3969 a.text = _str('Søk på nettetA') 3970 a.tail = "tail" 3971 b = SubElement(a, 'b') 3972 b.text = "B" 3973 b.tail = _str('Søk på nettetB') 3974 c = SubElement(a, 'c') 3975 c.text = "C" 3976 3977 self.assertRaises(UnicodeEncodeError, 3978 tostring, a, method="text") 3979 3980 self.assertEqual( 3981 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'), 3982 tostring(a, encoding="UTF-8", method="text"))
3983
3984 - def test_tounicode(self):
3985 tounicode = self.etree.tounicode 3986 Element = self.etree.Element 3987 SubElement = self.etree.SubElement 3988 3989 a = Element('a') 3990 b = SubElement(a, 'b') 3991 c = SubElement(a, 'c') 3992 3993 self.assertTrue(isinstance(tounicode(a), _unicode)) 3994 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 3995 canonicalize(tounicode(a)))
3996
3997 - def test_tounicode_element(self):
3998 tounicode = self.etree.tounicode 3999 Element = self.etree.Element 4000 SubElement = self.etree.SubElement 4001 4002 a = Element('a') 4003 b = SubElement(a, 'b') 4004 c = SubElement(a, 'c') 4005 d = SubElement(c, 'd') 4006 self.assertTrue(isinstance(tounicode(b), _unicode)) 4007 self.assertTrue(isinstance(tounicode(c), _unicode)) 4008 self.assertEqual(_bytes('<b></b>'), 4009 canonicalize(tounicode(b))) 4010 self.assertEqual(_bytes('<c><d></d></c>'), 4011 canonicalize(tounicode(c)))
4012
4013 - def test_tounicode_none(self):
4014 tounicode = self.etree.tounicode 4015 self.assertRaises(TypeError, self.etree.tounicode, None)
4016
4017 - def test_tounicode_element_tail(self):
4018 tounicode = self.etree.tounicode 4019 Element = self.etree.Element 4020 SubElement = self.etree.SubElement 4021 4022 a = Element('a') 4023 b = SubElement(a, 'b') 4024 c = SubElement(a, 'c') 4025 d = SubElement(c, 'd') 4026 b.tail = 'Foo' 4027 4028 self.assertTrue(isinstance(tounicode(b), _unicode)) 4029 self.assertTrue(tounicode(b) == '<b/>Foo' or 4030 tounicode(b) == '<b />Foo')
4031
4032 - def test_tounicode_pretty(self):
4033 tounicode = self.etree.tounicode 4034 Element = self.etree.Element 4035 SubElement = self.etree.SubElement 4036 4037 a = Element('a') 4038 b = SubElement(a, 'b') 4039 c = SubElement(a, 'c') 4040 4041 result = tounicode(a) 4042 self.assertEqual(result, "<a><b/><c/></a>") 4043 4044 result = tounicode(a, pretty_print=False) 4045 self.assertEqual(result, "<a><b/><c/></a>") 4046 4047 result = tounicode(a, pretty_print=True) 4048 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
4049
4050 - def test_tostring_unicode(self):
4051 tostring = self.etree.tostring 4052 Element = self.etree.Element 4053 SubElement = self.etree.SubElement 4054 4055 a = Element('a') 4056 b = SubElement(a, 'b') 4057 c = SubElement(a, 'c') 4058 4059 self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode)) 4060 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 4061 canonicalize(tostring(a, encoding=_unicode)))
4062
4063 - def test_tostring_unicode_element(self):
4064 tostring = self.etree.tostring 4065 Element = self.etree.Element 4066 SubElement = self.etree.SubElement 4067 4068 a = Element('a') 4069 b = SubElement(a, 'b') 4070 c = SubElement(a, 'c') 4071 d = SubElement(c, 'd') 4072 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 4073 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode)) 4074 self.assertEqual(_bytes('<b></b>'), 4075 canonicalize(tostring(b, encoding=_unicode))) 4076 self.assertEqual(_bytes('<c><d></d></c>'), 4077 canonicalize(tostring(c, encoding=_unicode)))
4078
4079 - def test_tostring_unicode_none(self):
4080 tostring = self.etree.tostring 4081 self.assertRaises(TypeError, self.etree.tostring, 4082 None, encoding=_unicode)
4083
4084 - def test_tostring_unicode_element_tail(self):
4085 tostring = self.etree.tostring 4086 Element = self.etree.Element 4087 SubElement = self.etree.SubElement 4088 4089 a = Element('a') 4090 b = SubElement(a, 'b') 4091 c = SubElement(a, 'c') 4092 d = SubElement(c, 'd') 4093 b.tail = 'Foo' 4094 4095 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 4096 self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or 4097 tostring(b, encoding=_unicode) == '<b />Foo')
4098
4099 - def test_tostring_unicode_pretty(self):
4100 tostring = self.etree.tostring 4101 Element = self.etree.Element 4102 SubElement = self.etree.SubElement 4103 4104 a = Element('a') 4105 b = SubElement(a, 'b') 4106 c = SubElement(a, 'c') 4107 4108 result = tostring(a, encoding=_unicode) 4109 self.assertEqual(result, "<a><b/><c/></a>") 4110 4111 result = tostring(a, encoding=_unicode, pretty_print=False) 4112 self.assertEqual(result, "<a><b/><c/></a>") 4113 4114 result = tostring(a, encoding=_unicode, pretty_print=True) 4115 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
4116
4117 - def test_pypy_proxy_collect(self):
4118 root = etree.Element('parent') 4119 etree.SubElement(root, 'child') 4120 4121 self.assertEqual(len(root), 1) 4122 self.assertEqual(root[0].tag, 'child') 4123 4124 # in PyPy, GC used to kill the Python proxy instance without cleanup 4125 gc.collect() 4126 self.assertEqual(len(root), 1) 4127 self.assertEqual(root[0].tag, 'child')
4128
4129 - def test_element_refcycle(self):
4130 class SubEl(etree.ElementBase): 4131 pass
4132 4133 el1 = SubEl() 4134 el2 = SubEl() 4135 self.assertEqual('SubEl', el1.tag) 4136 self.assertEqual('SubEl', el2.tag) 4137 el1.other = el2 4138 el2.other = el1 4139 4140 del el1, el2 4141 gc.collect() 4142 # not really testing anything here, but it shouldn't crash 4143
4144 - def test_proxy_collect_siblings(self):
4145 root = etree.Element('parent') 4146 c1 = etree.SubElement(root, 'child1') 4147 c2 = etree.SubElement(root, 'child2') 4148 4149 root.remove(c1) 4150 root.remove(c2) 4151 c1.addnext(c2) 4152 del c1 4153 # trigger deallocation attempt of c1 4154 c2.getprevious() 4155 # make sure it wasn't deallocated 4156 self.assertEqual('child1', c2.getprevious().tag)
4157
4158 - def test_proxy_collect_siblings_text(self):
4159 root = etree.Element('parent') 4160 c1 = etree.SubElement(root, 'child1') 4161 c2 = etree.SubElement(root, 'child2') 4162 4163 root.remove(c1) 4164 root.remove(c2) 4165 c1.addnext(c2) 4166 c1.tail = 'abc' 4167 c2.tail = 'xyz' 4168 del c1 4169 # trigger deallocation attempt of c1 4170 c2.getprevious() 4171 # make sure it wasn't deallocated 4172 self.assertEqual('child1', c2.getprevious().tag) 4173 self.assertEqual('abc', c2.getprevious().tail)
4174 4175 # helper methods 4176
4177 - def _writeElement(self, element, encoding='us-ascii', compression=0):
4178 """Write out element for comparison. 4179 """ 4180 ElementTree = self.etree.ElementTree 4181 f = BytesIO() 4182 tree = ElementTree(element=element) 4183 tree.write(f, encoding=encoding, compression=compression) 4184 data = f.getvalue() 4185 if compression: 4186 data = zlib.decompress(data) 4187 return canonicalize(data)
4188 4189
4190 -class _XIncludeTestCase(HelperTestCase):
4191 - def test_xinclude_text(self):
4192 filename = fileInTestDir('test_broken.xml') 4193 root = etree.XML(_bytes('''\ 4194 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 4195 <xi:include href="%s" parse="text"/> 4196 </doc> 4197 ''' % path2url(filename))) 4198 old_text = root.text 4199 content = read_file(filename) 4200 old_tail = root[0].tail 4201 4202 self.include( etree.ElementTree(root) ) 4203 self.assertEqual(old_text + content + old_tail, 4204 root.text)
4205
4206 - def test_xinclude(self):
4207 tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 4208 self.assertNotEqual( 4209 'a', 4210 tree.getroot()[1].tag) 4211 # process xincludes 4212 self.include( tree ) 4213 # check whether we find it replaced with included data 4214 self.assertEqual( 4215 'a', 4216 tree.getroot()[1].tag)
4217
4218 - def test_xinclude_resolver(self):
4219 class res(etree.Resolver): 4220 include_text = read_file(fileInTestDir('test.xml')) 4221 called = {} 4222 def resolve(self, url, id, context): 4223 if url.endswith(".dtd"): 4224 self.called["dtd"] = True 4225 return self.resolve_filename( 4226 fileInTestDir('test.dtd'), context) 4227 elif url.endswith("test_xinclude.xml"): 4228 self.called["input"] = True 4229 return None # delegate to default resolver 4230 else: 4231 self.called["include"] = True 4232 return self.resolve_string(self.include_text, context)
4233 4234 res_instance = res() 4235 parser = etree.XMLParser(load_dtd = True) 4236 parser.resolvers.add(res_instance) 4237 4238 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 4239 parser = parser) 4240 4241 self.include(tree) 4242 4243 called = list(res_instance.called.items()) 4244 called.sort() 4245 self.assertEqual( 4246 [("dtd", True), ("include", True), ("input", True)], 4247 called) 4248
4249 - def test_xinclude_resolver_recursive(self):
4250 data = textwrap.dedent(''' 4251 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 4252 <foo/> 4253 <xi:include href="./test.xml" /> 4254 </doc> 4255 ''') 4256 4257 class Resolver(etree.Resolver): 4258 called = {} 4259 4260 def resolve(self, url, id, context): 4261 if url.endswith("test_xinclude.xml"): 4262 assert not self.called.get("input") 4263 self.called["input"] = True 4264 return None # delegate to default resolver 4265 elif url.endswith('/test5.xml'): 4266 assert not self.called.get("DONE") 4267 self.called["DONE"] = True 4268 return self.resolve_string('<DONE/>', context) 4269 else: 4270 _, filename = url.rsplit('/', 1) 4271 assert not self.called.get(filename) 4272 self.called[filename] = True 4273 next_data = data.replace( 4274 'test.xml', 'test%d.xml' % len(self.called)) 4275 return self.resolve_string(next_data, context)
4276 4277 res_instance = Resolver() 4278 parser = etree.XMLParser(load_dtd=True) 4279 parser.resolvers.add(res_instance) 4280 4281 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 4282 parser=parser) 4283 4284 self.include(tree) 4285 4286 called = list(res_instance.called.items()) 4287 called.sort() 4288 self.assertEqual( 4289 [("DONE", True), ("input", True), ("test.xml", True), 4290 ("test2.xml", True), ("test3.xml", True), ("test4.xml", True)], 4291 called) 4292 4293
4294 -class ETreeXIncludeTestCase(_XIncludeTestCase):
4295 - def include(self, tree):
4296 tree.xinclude()
4297 4298
4299 -class ElementIncludeTestCase(_XIncludeTestCase):
4300 from lxml import ElementInclude 4301
4302 - def include(self, tree, loader=None, max_depth=None):
4303 self.ElementInclude.include(tree.getroot(), loader=loader, max_depth=max_depth)
4304 4305 XINCLUDE = {} 4306 4307 XINCLUDE["Recursive1.xml"] = """\ 4308 <?xml version='1.0'?> 4309 <document xmlns:xi="http://www.w3.org/2001/XInclude"> 4310 <p>The following is the source code of Recursive2.xml:</p> 4311 <xi:include href="Recursive2.xml"/> 4312 </document> 4313 """ 4314 4315 XINCLUDE["Recursive2.xml"] = """\ 4316 <?xml version='1.0'?> 4317 <document xmlns:xi="http://www.w3.org/2001/XInclude"> 4318 <p>The following is the source code of Recursive3.xml:</p> 4319 <xi:include href="Recursive3.xml"/> 4320 </document> 4321 """ 4322 4323 XINCLUDE["Recursive3.xml"] = """\ 4324 <?xml version='1.0'?> 4325 <document xmlns:xi="http://www.w3.org/2001/XInclude"> 4326 <p>The following is the source code of Recursive1.xml:</p> 4327 <xi:include href="Recursive1.xml"/> 4328 </document> 4329 """ 4330
4331 - def xinclude_loader(self, href, parse="xml", encoding=None):
4332 try: 4333 data = textwrap.dedent(self.XINCLUDE[href]) 4334 except KeyError: 4335 raise OSError("resource not found") 4336 if parse == "xml": 4337 data = etree.fromstring(data) 4338 return data
4339
4340 - def test_xinclude_failures(self):
4341 # Test infinitely recursive includes. 4342 document = self.xinclude_loader("Recursive1.xml").getroottree() 4343 with self.assertRaises(self.ElementInclude.FatalIncludeError) as cm: 4344 self.include(document, self.xinclude_loader) 4345 self.assertEqual(str(cm.exception), 4346 "recursive include of 'Recursive2.xml' detected") 4347 4348 # Test 'max_depth' limitation. 4349 document = self.xinclude_loader("Recursive1.xml").getroottree() 4350 with self.assertRaises(self.ElementInclude.FatalIncludeError) as cm: 4351 self.include(document, self.xinclude_loader, max_depth=None) 4352 self.assertEqual(str(cm.exception), 4353 "recursive include of 'Recursive2.xml' detected") 4354 4355 document = self.xinclude_loader("Recursive1.xml").getroottree() 4356 with self.assertRaises(self.ElementInclude.LimitedRecursiveIncludeError) as cm: 4357 self.include(document, self.xinclude_loader, max_depth=0) 4358 self.assertEqual(str(cm.exception), 4359 "maximum xinclude depth reached when including file Recursive2.xml") 4360 4361 document = self.xinclude_loader("Recursive1.xml").getroottree() 4362 with self.assertRaises(self.ElementInclude.LimitedRecursiveIncludeError) as cm: 4363 self.include(document, self.xinclude_loader, max_depth=1) 4364 self.assertEqual(str(cm.exception), 4365 "maximum xinclude depth reached when including file Recursive3.xml") 4366 4367 document = self.xinclude_loader("Recursive1.xml").getroottree() 4368 with self.assertRaises(self.ElementInclude.LimitedRecursiveIncludeError) as cm: 4369 self.include(document, self.xinclude_loader, max_depth=2) 4370 self.assertEqual(str(cm.exception), 4371 "maximum xinclude depth reached when including file Recursive1.xml") 4372 4373 document = self.xinclude_loader("Recursive1.xml").getroottree() 4374 with self.assertRaises(self.ElementInclude.FatalIncludeError) as cm: 4375 self.include(document, self.xinclude_loader, max_depth=3) 4376 self.assertEqual(str(cm.exception), 4377 "recursive include of 'Recursive2.xml' detected")
4378 4379
4380 -class ETreeC14NTestCase(HelperTestCase):
4381 - def test_c14n(self):
4382 tree = self.parse(_bytes('<a><b/></a>')) 4383 f = BytesIO() 4384 tree.write_c14n(f) 4385 s = f.getvalue() 4386 self.assertEqual(_bytes('<a><b></b></a>'), 4387 s)
4388
4389 - def test_c14n_gzip(self):
4390 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4391 f = BytesIO() 4392 tree.write_c14n(f, compression=9) 4393 with gzip.GzipFile(fileobj=BytesIO(f.getvalue())) as gzfile: 4394 s = gzfile.read() 4395 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 4396 s)
4397
4398 - def test_c14n_file(self):
4399 tree = self.parse(_bytes('<a><b/></a>')) 4400 with tmpfile() as filename: 4401 tree.write_c14n(filename) 4402 data = read_file(filename, 'rb') 4403 self.assertEqual(_bytes('<a><b></b></a>'), 4404 data)
4405
4406 - def test_c14n_file_gzip(self):
4407 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4408 with tmpfile() as filename: 4409 tree.write_c14n(filename, compression=9) 4410 with gzip.open(filename, 'rb') as f: 4411 data = f.read() 4412 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 4413 data)
4414
4415 - def test_c14n2_file_gzip(self):
4416 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4417 with tmpfile() as filename: 4418 tree.write(filename, method='c14n2', compression=9) 4419 with gzip.open(filename, 'rb') as f: 4420 data = f.read() 4421 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 4422 data)
4423
4424 - def test_c14n2_with_text(self):
4425 tree = self.parse( 4426 b'<?xml version="1.0"?> <a> abc \n <b> btext </b> btail <c/> ctail </a> ') 4427 f = BytesIO() 4428 tree.write(f, method='c14n2') 4429 s = f.getvalue() 4430 self.assertEqual(b'<a> abc \n <b> btext </b> btail <c></c> ctail </a>', 4431 s) 4432 4433 f = BytesIO() 4434 tree.write(f, method='c14n2', strip_text=True) 4435 s = f.getvalue() 4436 self.assertEqual(b'<a>abc<b>btext</b>btail<c></c>ctail</a>', 4437 s)
4438
4439 - def test_c14n_with_comments(self):
4440 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 4441 f = BytesIO() 4442 tree.write_c14n(f) 4443 s = f.getvalue() 4444 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 4445 s) 4446 f = BytesIO() 4447 tree.write_c14n(f, with_comments=True) 4448 s = f.getvalue() 4449 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 4450 s) 4451 f = BytesIO() 4452 tree.write_c14n(f, with_comments=False) 4453 s = f.getvalue() 4454 self.assertEqual(_bytes('<a><b></b></a>'), 4455 s)
4456
4457 - def test_c14n2_with_comments(self):
4458 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 4459 f = BytesIO() 4460 tree.write(f, method='c14n2') 4461 s = f.getvalue() 4462 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 4463 s) 4464 f = BytesIO() 4465 tree.write(f, method='c14n2', with_comments=True) 4466 s = f.getvalue() 4467 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 4468 s) 4469 f = BytesIO() 4470 tree.write(f, method='c14n2', with_comments=False) 4471 s = f.getvalue() 4472 self.assertEqual(_bytes('<a><b></b></a>'), 4473 s)
4474
4476 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 4477 s = etree.tostring(tree, method='c14n') 4478 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 4479 s) 4480 s = etree.tostring(tree, method='c14n', with_comments=True) 4481 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 4482 s) 4483 s = etree.tostring(tree, method='c14n', with_comments=False) 4484 self.assertEqual(_bytes('<a><b></b></a>'), 4485 s)
4486
4488 tree = self.parse(b'<!--hi--><a><!--ho--><b/></a><!--hu-->') 4489 s = etree.tostring(tree, method='c14n2') 4490 self.assertEqual(b'<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->', 4491 s) 4492 s = etree.tostring(tree, method='c14n2', with_comments=True) 4493 self.assertEqual(b'<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->', 4494 s) 4495 s = etree.tostring(tree, method='c14n2', with_comments=False) 4496 self.assertEqual(b'<a><b></b></a>', 4497 s)
4498
4500 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 4501 s = etree.tostring(tree.getroot(), method='c14n') 4502 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 4503 s) 4504 s = etree.tostring(tree.getroot(), method='c14n', with_comments=True) 4505 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 4506 s) 4507 s = etree.tostring(tree.getroot(), method='c14n', with_comments=False) 4508 self.assertEqual(_bytes('<a><b></b></a>'), 4509 s)
4510
4511 - def test_c14n_exclusive(self):
4512 tree = self.parse(_bytes( 4513 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 4514 f = BytesIO() 4515 tree.write_c14n(f) 4516 s = f.getvalue() 4517 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4518 s) 4519 f = BytesIO() 4520 tree.write_c14n(f, exclusive=False) 4521 s = f.getvalue() 4522 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4523 s) 4524 f = BytesIO() 4525 tree.write_c14n(f, exclusive=True) 4526 s = f.getvalue() 4527 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 4528 s) 4529 4530 f = BytesIO() 4531 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z']) 4532 s = f.getvalue() 4533 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'), 4534 s)
4535
4537 tree = self.parse(_bytes( 4538 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 4539 s = etree.tostring(tree, method='c14n') 4540 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4541 s) 4542 s = etree.tostring(tree, method='c14n', exclusive=False) 4543 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4544 s) 4545 s = etree.tostring(tree, method='c14n', exclusive=True) 4546 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 4547 s) 4548 4549 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 4550 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'), 4551 s)
4552
4554 tree = self.parse(_bytes( 4555 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 4556 s = etree.tostring(tree.getroot(), method='c14n') 4557 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4558 s) 4559 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False) 4560 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4561 s) 4562 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True) 4563 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 4564 s) 4565 4566 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False) 4567 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 4568 s) 4569 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True) 4570 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'), 4571 s) 4572 4573 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 4574 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 4575 s)
4576
4578 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)""" 4579 tree = self.parse(_bytes( 4580 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 4581 4582 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z']) 4583 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4584 s)
4585 4586
4587 -class ETreeWriteTestCase(HelperTestCase):
4588 - def test_write(self):
4589 tree = self.parse(_bytes('<a><b/></a>')) 4590 f = BytesIO() 4591 tree.write(f) 4592 s = f.getvalue() 4593 self.assertEqual(_bytes('<a><b/></a>'), 4594 s)
4595
4596 - def test_write_doctype(self):
4597 tree = self.parse(_bytes('<a><b/></a>')) 4598 f = BytesIO() 4599 tree.write(f, doctype='HUHU') 4600 s = f.getvalue() 4601 self.assertEqual(_bytes('HUHU\n<a><b/></a>'), 4602 s)
4603
4604 - def test_write_gzip(self):
4605 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4606 f = BytesIO() 4607 tree.write(f, compression=9) 4608 with gzip.GzipFile(fileobj=BytesIO(f.getvalue())) as gzfile: 4609 s = gzfile.read() 4610 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4611 s)
4612
4613 - def test_write_gzip_doctype(self):
4614 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4615 f = BytesIO() 4616 tree.write(f, compression=9, doctype='<!DOCTYPE a>') 4617 with gzip.GzipFile(fileobj=BytesIO(f.getvalue())) as gzfile: 4618 s = gzfile.read() 4619 self.assertEqual(_bytes('<!DOCTYPE a>\n<a>'+'<b/>'*200+'</a>'), 4620 s)
4621
4622 - def test_write_gzip_level(self):
4623 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4624 f = BytesIO() 4625 tree.write(f, compression=0) 4626 s0 = f.getvalue() 4627 4628 f = BytesIO() 4629 tree.write(f) 4630 self.assertEqual(f.getvalue(), s0) 4631 4632 f = BytesIO() 4633 tree.write(f, compression=1) 4634 s = f.getvalue() 4635 self.assertTrue(len(s) <= len(s0)) 4636 with gzip.GzipFile(fileobj=BytesIO(s)) as gzfile: 4637 s1 = gzfile.read() 4638 4639 f = BytesIO() 4640 tree.write(f, compression=9) 4641 s = f.getvalue() 4642 self.assertTrue(len(s) <= len(s0)) 4643 with gzip.GzipFile(fileobj=BytesIO(s)) as gzfile: 4644 s9 = gzfile.read() 4645 4646 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4647 s0) 4648 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4649 s1) 4650 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4651 s9)
4652
4653 - def test_write_file(self):
4654 tree = self.parse(_bytes('<a><b/></a>')) 4655 with tmpfile() as filename: 4656 tree.write(filename) 4657 data = read_file(filename, 'rb') 4658 self.assertEqual(_bytes('<a><b/></a>'), 4659 data)
4660
4661 - def test_write_file_gzip(self):
4662 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4663 with tmpfile() as filename: 4664 tree.write(filename, compression=9) 4665 with gzip.open(filename, 'rb') as f: 4666 data = f.read() 4667 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4668 data)
4669
4670 - def test_write_file_gzip_parse(self):
4671 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4672 with tmpfile() as filename: 4673 tree.write(filename, compression=9) 4674 data = etree.tostring(etree.parse(filename)) 4675 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4676 data)
4677
4679 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4680 with tmpfile() as filename: 4681 tree.write(filename, compression=9) 4682 with gzip.GzipFile(filename) as f: 4683 data = etree.tostring(etree.parse(f)) 4684 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4685 data)
4686
4687 - def test_write_file_url(self):
4688 xml = _bytes('<a>'+'<b/>'*200+'</a>') 4689 tree = self.parse(xml) 4690 with tmpfile(prefix="p+%20", suffix=".xml") as filename: 4691 url = 'file://' + (filename if sys.platform != 'win32' 4692 else '/' + filename.replace('\\', '/')) 4693 tree.write(url) 4694 data = read_file(filename, 'rb').replace(_bytes('\n'), _bytes('')) 4695 self.assertEqual(data, xml)
4696 4697
4698 -class ETreeErrorLogTest(HelperTestCase):
4699 etree = etree 4700
4701 - def test_parse_error_logging(self):
4702 parse = self.etree.parse 4703 f = BytesIO('<a><b></c></b></a>') 4704 self.etree.clear_error_log() 4705 try: 4706 parse(f) 4707 logs = None 4708 except SyntaxError: 4709 e = sys.exc_info()[1] 4710 logs = e.error_log 4711 f.close() 4712 self.assertTrue([ log for log in logs 4713 if 'mismatch' in log.message ]) 4714 self.assertTrue([ log for log in logs 4715 if 'PARSER' in log.domain_name]) 4716 self.assertTrue([ log for log in logs 4717 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ]) 4718 self.assertTrue([ log for log in logs 4719 if 1 == log.line ]) 4720 self.assertTrue([ log for log in logs 4721 if 15 == log.column ])
4722
4723 - def _test_python_error_logging(self):
4724 """This can't really be tested as long as there isn't a way to 4725 reset the logging setup ... 4726 """ 4727 parse = self.etree.parse 4728 4729 messages = [] 4730 class Logger(self.etree.PyErrorLog): 4731 def log(self, entry, message, *args): 4732 messages.append(message)
4733 4734 self.etree.use_global_python_log(Logger()) 4735 f = BytesIO('<a><b></c></b></a>') 4736 try: 4737 parse(f) 4738 except SyntaxError: 4739 pass 4740 f.close() 4741 4742 self.assertTrue([ message for message in messages 4743 if 'mismatch' in message ]) 4744 self.assertTrue([ message for message in messages 4745 if ':PARSER:' in message]) 4746 self.assertTrue([ message for message in messages 4747 if ':ERR_TAG_NAME_MISMATCH:' in message ]) 4748 self.assertTrue([ message for message in messages 4749 if ':1:15:' in message ]) 4750 4751
4752 -class XMLPullParserTest(unittest.TestCase):
4753 etree = etree 4754
4755 - def assert_event_tags(self, events, expected):
4756 self.assertEqual([(action, elem.tag) for action, elem in events], 4757 expected)
4758
4760 class Target(object): 4761 def start(self, tag, attrib): 4762 return 'start(%s)' % tag
4763 def end(self, tag): 4764 return 'end(%s)' % tag
4765 def close(self): 4766 return 'close()' 4767 4768 parser = self.etree.XMLPullParser(target=Target()) 4769 events = parser.read_events() 4770 4771 parser.feed('<root><element>') 4772 self.assertFalse(list(events)) 4773 self.assertFalse(list(events)) 4774 parser.feed('</element><child>') 4775 self.assertEqual([('end', 'end(element)')], list(events)) 4776 parser.feed('</child>') 4777 self.assertEqual([('end', 'end(child)')], list(events)) 4778 parser.feed('</root>') 4779 self.assertEqual([('end', 'end(root)')], list(events)) 4780 self.assertFalse(list(events)) 4781 self.assertEqual('close()', parser.close()) 4782
4783 - def test_pull_from_simple_target_start_end(self):
4784 class Target(object): 4785 def start(self, tag, attrib): 4786 return 'start(%s)' % tag
4787 def end(self, tag): 4788 return 'end(%s)' % tag 4789 def close(self): 4790 return 'close()' 4791 4792 parser = self.etree.XMLPullParser( 4793 ['start', 'end'], target=Target()) 4794 events = parser.read_events() 4795 4796 parser.feed('<root><element>') 4797 self.assertEqual( 4798 [('start', 'start(root)'), ('start', 'start(element)')], 4799 list(events)) 4800 self.assertFalse(list(events)) 4801 parser.feed('</element><child>') 4802 self.assertEqual( 4803 [('end', 'end(element)'), ('start', 'start(child)')], 4804 list(events)) 4805 parser.feed('</child>') 4806 self.assertEqual( 4807 [('end', 'end(child)')], 4808 list(events)) 4809 parser.feed('</root>') 4810 self.assertEqual( 4811 [('end', 'end(root)')], 4812 list(events)) 4813 self.assertFalse(list(events)) 4814 self.assertEqual('close()', parser.close()) 4815
4816 - def test_pull_from_tree_builder(self):
4817 parser = self.etree.XMLPullParser( 4818 ['start', 'end'], target=etree.TreeBuilder()) 4819 events = parser.read_events() 4820 4821 parser.feed('<root><element>') 4822 self.assert_event_tags( 4823 events, [('start', 'root'), ('start', 'element')]) 4824 self.assertFalse(list(events)) 4825 parser.feed('</element><child>') 4826 self.assert_event_tags( 4827 events, [('end', 'element'), ('start', 'child')]) 4828 parser.feed('</child>') 4829 self.assert_event_tags( 4830 events, [('end', 'child')]) 4831 parser.feed('</root>') 4832 self.assert_event_tags( 4833 events, [('end', 'root')]) 4834 self.assertFalse(list(events)) 4835 root = parser.close() 4836 self.assertEqual('root', root.tag)
4837
4838 - def test_pull_from_tree_builder_subclass(self):
4839 class Target(etree.TreeBuilder): 4840 def end(self, tag): 4841 el = super(Target, self).end(tag) 4842 el.tag += '-huhu' 4843 return el
4844 4845 parser = self.etree.XMLPullParser( 4846 ['start', 'end'], target=Target()) 4847 events = parser.read_events() 4848 4849 parser.feed('<root><element>') 4850 self.assert_event_tags( 4851 events, [('start', 'root'), ('start', 'element')]) 4852 self.assertFalse(list(events)) 4853 parser.feed('</element><child>') 4854 self.assert_event_tags( 4855 events, [('end', 'element-huhu'), ('start', 'child')]) 4856 parser.feed('</child>') 4857 self.assert_event_tags( 4858 events, [('end', 'child-huhu')]) 4859 parser.feed('</root>') 4860 self.assert_event_tags( 4861 events, [('end', 'root-huhu')]) 4862 self.assertFalse(list(events)) 4863 root = parser.close() 4864 self.assertEqual('root-huhu', root.tag) 4865 4866
4867 -def test_suite():
4868 suite = unittest.TestSuite() 4869 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 4870 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 4871 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 4872 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 4873 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)]) 4874 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)]) 4875 suite.addTests([unittest.makeSuite(XMLPullParserTest)]) 4876 4877 # add original doctests from ElementTree selftest modules 4878 from . import selftest, selftest2 4879 suite.addTests(doctest.DocTestSuite(selftest)) 4880 suite.addTests(doctest.DocTestSuite(selftest2)) 4881 4882 # add doctests 4883 suite.addTests(doctest.DocTestSuite(etree)) 4884 suite.addTests( 4885 [make_doctest('../../../doc/tutorial.txt')]) 4886 suite.addTests( 4887 [make_doctest('../../../doc/api.txt')]) 4888 suite.addTests( 4889 [make_doctest('../../../doc/FAQ.txt')]) 4890 suite.addTests( 4891 [make_doctest('../../../doc/parsing.txt')]) 4892 suite.addTests( 4893 [make_doctest('../../../doc/resolvers.txt')]) 4894 return suite
4895 4896 4897 if __name__ == '__main__': 4898 print('to test use test.py %s' % __file__) 4899