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