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