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