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