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_type(self):
1446 CDATA = self.etree.CDATA 1447 Element = self.etree.Element 1448 root = Element("root") 1449 1450 root.text = CDATA("test") 1451 self.assertEqual('test', root.text) 1452 1453 root.text = CDATA(_str("test")) 1454 self.assertEqual('test', root.text) 1455 1456 self.assertRaises(TypeError, CDATA, 1)
1457
1458 - def test_cdata_errors(self):
1459 CDATA = self.etree.CDATA 1460 Element = self.etree.Element 1461 1462 root = Element("root") 1463 cdata = CDATA('test') 1464 1465 self.assertRaises(TypeError, 1466 setattr, root, 'tail', cdata) 1467 self.assertRaises(TypeError, 1468 root.set, 'attr', cdata) 1469 self.assertRaises(TypeError, 1470 operator.setitem, root.attrib, 'attr', cdata)
1471
1472 - def test_cdata_parser(self):
1473 tostring = self.etree.tostring 1474 parser = self.etree.XMLParser(strip_cdata=False) 1475 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1476 1477 self.assertEqual('test', root.text) 1478 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 1479 tostring(root))
1480
1481 - def test_cdata_xpath(self):
1482 tostring = self.etree.tostring 1483 parser = self.etree.XMLParser(strip_cdata=False) 1484 root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 1485 self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 1486 tostring(root)) 1487 1488 self.assertEqual(['test'], root.xpath('//text()'))
1489 1490 # TypeError in etree, AssertionError in ElementTree;
1491 - def test_setitem_assert(self):
1492 Element = self.etree.Element 1493 SubElement = self.etree.SubElement 1494 1495 a = Element('a') 1496 b = SubElement(a, 'b') 1497 1498 self.assertRaises(TypeError, 1499 a.__setitem__, 0, 'foo')
1500
1501 - def test_append_error(self):
1502 Element = self.etree.Element 1503 root = Element('root') 1504 # raises AssertionError in ElementTree 1505 self.assertRaises(TypeError, root.append, None) 1506 self.assertRaises(TypeError, root.extend, [None]) 1507 self.assertRaises(TypeError, root.extend, [Element('one'), None]) 1508 self.assertEqual('one', root[0].tag)
1509
1510 - def test_append_recursive_error(self):
1511 Element = self.etree.Element 1512 SubElement = self.etree.SubElement 1513 root = Element('root') 1514 self.assertRaises(ValueError, root.append, root) 1515 child = SubElement(root, 'child') 1516 self.assertRaises(ValueError, child.append, root) 1517 child2 = SubElement(child, 'child2') 1518 self.assertRaises(ValueError, child2.append, root) 1519 self.assertRaises(ValueError, child2.append, child) 1520 self.assertEqual('child2', root[0][0].tag)
1521
1522 - def test_addnext(self):
1523 Element = self.etree.Element 1524 SubElement = self.etree.SubElement 1525 root = Element('root') 1526 SubElement(root, 'a') 1527 SubElement(root, 'b') 1528 1529 self.assertEqual(['a', 'b'], 1530 [c.tag for c in root]) 1531 root[1].addnext(root[0]) 1532 self.assertEqual(['b', 'a'], 1533 [c.tag for c in root])
1534
1535 - def test_addprevious(self):
1536 Element = self.etree.Element 1537 SubElement = self.etree.SubElement 1538 root = Element('root') 1539 SubElement(root, 'a') 1540 SubElement(root, 'b') 1541 1542 self.assertEqual(['a', 'b'], 1543 [c.tag for c in root]) 1544 root[0].addprevious(root[1]) 1545 self.assertEqual(['b', 'a'], 1546 [c.tag for c in root])
1547
1548 - def test_addnext_cycle(self):
1549 Element = self.etree.Element 1550 SubElement = self.etree.SubElement 1551 root = Element('root') 1552 a = SubElement(root, 'a') 1553 b = SubElement(a, 'b') 1554 # appending parent as sibling is forbidden 1555 self.assertRaises(ValueError, b.addnext, a) 1556 self.assertEqual(['a'], [c.tag for c in root]) 1557 self.assertEqual(['b'], [c.tag for c in a])
1558
1559 - def test_addprevious_cycle(self):
1560 Element = self.etree.Element 1561 SubElement = self.etree.SubElement 1562 root = Element('root') 1563 a = SubElement(root, 'a') 1564 b = SubElement(a, 'b') 1565 # appending parent as sibling is forbidden 1566 self.assertRaises(ValueError, b.addprevious, a) 1567 self.assertEqual(['a'], [c.tag for c in root]) 1568 self.assertEqual(['b'], [c.tag for c in a])
1569
1570 - def test_addnext_cycle_long(self):
1571 Element = self.etree.Element 1572 SubElement = self.etree.SubElement 1573 root = Element('root') 1574 a = SubElement(root, 'a') 1575 b = SubElement(a, 'b') 1576 c = SubElement(b, 'c') 1577 # appending parent as sibling is forbidden 1578 self.assertRaises(ValueError, c.addnext, a)
1579
1580 - def test_addprevious_cycle_long(self):
1581 Element = self.etree.Element 1582 SubElement = self.etree.SubElement 1583 root = Element('root') 1584 a = SubElement(root, 'a') 1585 b = SubElement(a, 'b') 1586 c = SubElement(b, 'c') 1587 # appending parent as sibling is forbidden 1588 self.assertRaises(ValueError, c.addprevious, a)
1589
1590 - def test_addprevious_noops(self):
1591 Element = self.etree.Element 1592 SubElement = self.etree.SubElement 1593 root = Element('root') 1594 a = SubElement(root, 'a') 1595 b = SubElement(root, 'b') 1596 a.addprevious(a) 1597 self.assertEqual('a', root[0].tag) 1598 self.assertEqual('b', root[1].tag) 1599 b.addprevious(b) 1600 self.assertEqual('a', root[0].tag) 1601 self.assertEqual('b', root[1].tag) 1602 b.addprevious(a) 1603 self.assertEqual('a', root[0].tag) 1604 self.assertEqual('b', root[1].tag)
1605
1606 - def test_addnext_noops(self):
1607 Element = self.etree.Element 1608 SubElement = self.etree.SubElement 1609 root = Element('root') 1610 a = SubElement(root, 'a') 1611 b = SubElement(root, 'b') 1612 a.addnext(a) 1613 self.assertEqual('a', root[0].tag) 1614 self.assertEqual('b', root[1].tag) 1615 b.addnext(b) 1616 self.assertEqual('a', root[0].tag) 1617 self.assertEqual('b', root[1].tag) 1618 a.addnext(b) 1619 self.assertEqual('a', root[0].tag) 1620 self.assertEqual('b', root[1].tag)
1621
1622 - def test_addnext_root(self):
1623 Element = self.etree.Element 1624 a = Element('a') 1625 b = Element('b') 1626 self.assertRaises(TypeError, a.addnext, b)
1627
1628 - def test_addprevious_pi(self):
1629 Element = self.etree.Element 1630 SubElement = self.etree.SubElement 1631 PI = self.etree.PI 1632 root = Element('root') 1633 SubElement(root, 'a') 1634 pi = PI('TARGET', 'TEXT') 1635 pi.tail = "TAIL" 1636 1637 self.assertEqual(_bytes('<root><a></a></root>'), 1638 self._writeElement(root)) 1639 root[0].addprevious(pi) 1640 self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'), 1641 self._writeElement(root))
1642
1643 - def test_addprevious_root_pi(self):
1644 Element = self.etree.Element 1645 PI = self.etree.PI 1646 root = Element('root') 1647 pi = PI('TARGET', 'TEXT') 1648 pi.tail = "TAIL" 1649 1650 self.assertEqual(_bytes('<root></root>'), 1651 self._writeElement(root)) 1652 root.addprevious(pi) 1653 self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'), 1654 self._writeElement(root))
1655
1656 - def test_addnext_pi(self):
1657 Element = self.etree.Element 1658 SubElement = self.etree.SubElement 1659 PI = self.etree.PI 1660 root = Element('root') 1661 SubElement(root, 'a') 1662 pi = PI('TARGET', 'TEXT') 1663 pi.tail = "TAIL" 1664 1665 self.assertEqual(_bytes('<root><a></a></root>'), 1666 self._writeElement(root)) 1667 root[0].addnext(pi) 1668 self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'), 1669 self._writeElement(root))
1670
1671 - def test_addnext_root_pi(self):
1672 Element = self.etree.Element 1673 PI = self.etree.PI 1674 root = Element('root') 1675 pi = PI('TARGET', 'TEXT') 1676 pi.tail = "TAIL" 1677 1678 self.assertEqual(_bytes('<root></root>'), 1679 self._writeElement(root)) 1680 root.addnext(pi) 1681 self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'), 1682 self._writeElement(root))
1683
1684 - def test_addnext_comment(self):
1685 Element = self.etree.Element 1686 SubElement = self.etree.SubElement 1687 Comment = self.etree.Comment 1688 root = Element('root') 1689 SubElement(root, 'a') 1690 comment = Comment('TEXT ') 1691 comment.tail = "TAIL" 1692 1693 self.assertEqual(_bytes('<root><a></a></root>'), 1694 self._writeElement(root)) 1695 root[0].addnext(comment) 1696 self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'), 1697 self._writeElement(root))
1698
1699 - def test_addnext_root_comment(self):
1700 Element = self.etree.Element 1701 Comment = self.etree.Comment 1702 root = Element('root') 1703 comment = Comment('TEXT ') 1704 comment.tail = "TAIL" 1705 1706 self.assertEqual(_bytes('<root></root>'), 1707 self._writeElement(root)) 1708 root.addnext(comment) 1709 self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'), 1710 self._writeElement(root))
1711
1712 - def test_addprevious_comment(self):
1713 Element = self.etree.Element 1714 SubElement = self.etree.SubElement 1715 Comment = self.etree.Comment 1716 root = Element('root') 1717 SubElement(root, 'a') 1718 comment = Comment('TEXT ') 1719 comment.tail = "TAIL" 1720 1721 self.assertEqual(_bytes('<root><a></a></root>'), 1722 self._writeElement(root)) 1723 root[0].addprevious(comment) 1724 self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'), 1725 self._writeElement(root))
1726
1727 - def test_addprevious_root_comment(self):
1728 Element = self.etree.Element 1729 Comment = self.etree.Comment 1730 root = Element('root') 1731 comment = Comment('TEXT ') 1732 comment.tail = "TAIL" 1733 1734 self.assertEqual(_bytes('<root></root>'), 1735 self._writeElement(root)) 1736 root.addprevious(comment) 1737 self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'), 1738 self._writeElement(root))
1739 1740 # ET's Elements have items() and key(), but not values()
1741 - def test_attribute_values(self):
1742 XML = self.etree.XML 1743 1744 root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')) 1745 values = root.values() 1746 values.sort() 1747 self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
1748 1749 # gives error in ElementTree
1750 - def test_comment_empty(self):
1751 Element = self.etree.Element 1752 Comment = self.etree.Comment 1753 1754 a = Element('a') 1755 a.append(Comment()) 1756 self.assertEqual( 1757 _bytes('<a><!----></a>'), 1758 self._writeElement(a))
1759 1760 # ElementTree ignores comments
1761 - def test_comment_parse_empty(self):
1762 ElementTree = self.etree.ElementTree 1763 tostring = self.etree.tostring 1764 1765 xml = _bytes('<a><b/><!----><c/></a>') 1766 f = BytesIO(xml) 1767 doc = ElementTree(file=f) 1768 a = doc.getroot() 1769 self.assertEqual( 1770 '', 1771 a[1].text) 1772 self.assertEqual( 1773 xml, 1774 tostring(a))
1775 1776 # ElementTree ignores comments
1777 - def test_comment_no_proxy_yet(self):
1778 ElementTree = self.etree.ElementTree 1779 1780 f = BytesIO('<a><b></b><!-- hoi --><c></c></a>') 1781 doc = ElementTree(file=f) 1782 a = doc.getroot() 1783 self.assertEqual( 1784 ' hoi ', 1785 a[1].text)
1786 1787 # does not raise an exception in ElementTree
1788 - def test_comment_immutable(self):
1789 Element = self.etree.Element 1790 Comment = self.etree.Comment 1791 1792 c = Comment() 1793 el = Element('myel') 1794 1795 self.assertRaises(TypeError, c.append, el) 1796 self.assertRaises(TypeError, c.insert, 0, el) 1797 self.assertRaises(TypeError, c.set, "myattr", "test")
1798
1799 - def test_comment_immutable_attrib(self):
1800 c = self.etree.Comment() 1801 self.assertEqual(0, len(c.attrib)) 1802 1803 self.assertFalse(c.attrib.__contains__('nope')) 1804 self.assertFalse('nope' in c.attrib) 1805 self.assertFalse('nope' in c.attrib.keys()) 1806 self.assertFalse('nope' in c.attrib.values()) 1807 self.assertFalse(('nope', 'huhu') in c.attrib.items()) 1808 1809 self.assertEqual([], list(c.attrib)) 1810 self.assertEqual([], list(c.attrib.keys())) 1811 self.assertEqual([], list(c.attrib.items())) 1812 self.assertEqual([], list(c.attrib.values())) 1813 self.assertEqual([], list(c.attrib.iterkeys())) 1814 self.assertEqual([], list(c.attrib.iteritems())) 1815 self.assertEqual([], list(c.attrib.itervalues())) 1816 1817 self.assertEqual('HUHU', c.attrib.pop('nope', 'HUHU')) 1818 self.assertRaises(KeyError, c.attrib.pop, 'nope') 1819 1820 self.assertRaises(KeyError, c.attrib.__getitem__, 'only') 1821 self.assertRaises(KeyError, c.attrib.__getitem__, 'names') 1822 self.assertRaises(KeyError, c.attrib.__getitem__, 'nope') 1823 self.assertRaises(KeyError, c.attrib.__setitem__, 'nope', 'yep') 1824 self.assertRaises(KeyError, c.attrib.__delitem__, 'nope')
1825 1826 # test passing 'None' to dump()
1827 - def test_dump_none(self):
1828 self.assertRaises(TypeError, self.etree.dump, None)
1829
1830 - def test_prefix(self):
1831 ElementTree = self.etree.ElementTree 1832 1833 f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 1834 doc = ElementTree(file=f) 1835 a = doc.getroot() 1836 self.assertEqual( 1837 None, 1838 a.prefix) 1839 self.assertEqual( 1840 'foo', 1841 a[0].prefix)
1842
1843 - def test_prefix_default_ns(self):
1844 ElementTree = self.etree.ElementTree 1845 1846 f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 1847 doc = ElementTree(file=f) 1848 a = doc.getroot() 1849 self.assertEqual( 1850 None, 1851 a.prefix) 1852 self.assertEqual( 1853 None, 1854 a[0].prefix)
1855
1856 - def test_getparent(self):
1857 Element = self.etree.Element 1858 SubElement = self.etree.SubElement 1859 1860 a = Element('a') 1861 b = SubElement(a, 'b') 1862 c = SubElement(a, 'c') 1863 d = SubElement(b, 'd') 1864 self.assertEqual( 1865 None, 1866 a.getparent()) 1867 self.assertEqual( 1868 a, 1869 b.getparent()) 1870 self.assertEqual( 1871 b.getparent(), 1872 c.getparent()) 1873 self.assertEqual( 1874 b, 1875 d.getparent())
1876
1877 - def test_iterchildren(self):
1878 XML = self.etree.XML 1879 1880 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1881 result = [] 1882 for el in root.iterchildren(): 1883 result.append(el.tag) 1884 self.assertEqual(['one', 'two', 'three'], result)
1885
1886 - def test_iterchildren_reversed(self):
1887 XML = self.etree.XML 1888 1889 root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 1890 result = [] 1891 for el in root.iterchildren(reversed=True): 1892 result.append(el.tag) 1893 self.assertEqual(['three', 'two', 'one'], result)
1894
1895 - def test_iterchildren_tag(self):
1896 XML = self.etree.XML 1897 1898 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1899 result = [] 1900 for el in root.iterchildren(tag='two'): 1901 result.append(el.text) 1902 self.assertEqual(['Two', 'Bla'], result)
1903
1904 - def test_iterchildren_tag_posarg(self):
1905 XML = self.etree.XML 1906 1907 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1908 result = [] 1909 for el in root.iterchildren('two'): 1910 result.append(el.text) 1911 self.assertEqual(['Two', 'Bla'], result)
1912
1913 - def test_iterchildren_tag_reversed(self):
1914 XML = self.etree.XML 1915 1916 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 1917 result = [] 1918 for el in root.iterchildren(reversed=True, tag='two'): 1919 result.append(el.text) 1920 self.assertEqual(['Bla', 'Two'], result)
1921
1922 - def test_iterchildren_tag_multiple(self):
1923 XML = self.etree.XML 1924 1925 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 1926 result = [] 1927 for el in root.iterchildren(tag=['two', 'three']): 1928 result.append(el.text) 1929 self.assertEqual(['Two', 'Bla', None], result)
1930
1931 - def test_iterchildren_tag_multiple_posarg(self):
1932 XML = self.etree.XML 1933 1934 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 1935 result = [] 1936 for el in root.iterchildren('two', 'three'): 1937 result.append(el.text) 1938 self.assertEqual(['Two', 'Bla', None], result)
1939
1940 - def test_iterchildren_tag_multiple_reversed(self):
1941 XML = self.etree.XML 1942 1943 root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 1944 result = [] 1945 for el in root.iterchildren(reversed=True, tag=['two', 'three']): 1946 result.append(el.text) 1947 self.assertEqual([None, 'Bla', 'Two'], result)
1948
1949 - def test_iterancestors(self):
1950 Element = self.etree.Element 1951 SubElement = self.etree.SubElement 1952 1953 a = Element('a') 1954 b = SubElement(a, 'b') 1955 c = SubElement(a, 'c') 1956 d = SubElement(b, 'd') 1957 self.assertEqual( 1958 [], 1959 list(a.iterancestors())) 1960 self.assertEqual( 1961 [a], 1962 list(b.iterancestors())) 1963 self.assertEqual( 1964 [a], 1965 list(c.iterancestors())) 1966 self.assertEqual( 1967 [b, a], 1968 list(d.iterancestors()))
1969
1970 - def test_iterancestors_tag(self):
1971 Element = self.etree.Element 1972 SubElement = self.etree.SubElement 1973 1974 a = Element('a') 1975 b = SubElement(a, 'b') 1976 c = SubElement(a, 'c') 1977 d = SubElement(b, 'd') 1978 self.assertEqual( 1979 [a], 1980 list(d.iterancestors('a'))) 1981 self.assertEqual( 1982 [a], 1983 list(d.iterancestors(tag='a'))) 1984 1985 self.assertEqual( 1986 [b, a], 1987 list(d.iterancestors('*'))) 1988 self.assertEqual( 1989 [b, a], 1990 list(d.iterancestors(tag='*')))
1991
1992 - def test_iterancestors_tag_multiple(self):
1993 Element = self.etree.Element 1994 SubElement = self.etree.SubElement 1995 1996 a = Element('a') 1997 b = SubElement(a, 'b') 1998 c = SubElement(a, 'c') 1999 d = SubElement(b, 'd') 2000 self.assertEqual( 2001 [b, a], 2002 list(d.iterancestors(tag=('a', 'b')))) 2003 self.assertEqual( 2004 [b, a], 2005 list(d.iterancestors('a', 'b'))) 2006 2007 self.assertEqual( 2008 [], 2009 list(d.iterancestors(tag=('w', 'x', 'y', 'z')))) 2010 self.assertEqual( 2011 [], 2012 list(d.iterancestors('w', 'x', 'y', 'z'))) 2013 2014 self.assertEqual( 2015 [], 2016 list(d.iterancestors(tag=('d', 'x')))) 2017 self.assertEqual( 2018 [], 2019 list(d.iterancestors('d', 'x'))) 2020 2021 self.assertEqual( 2022 [b, a], 2023 list(d.iterancestors(tag=('b', '*')))) 2024 self.assertEqual( 2025 [b, a], 2026 list(d.iterancestors('b', '*'))) 2027 2028 self.assertEqual( 2029 [b], 2030 list(d.iterancestors(tag=('b', 'c')))) 2031 self.assertEqual( 2032 [b], 2033 list(d.iterancestors('b', 'c')))
2034
2035 - def test_iterdescendants(self):
2036 Element = self.etree.Element 2037 SubElement = self.etree.SubElement 2038 2039 a = Element('a') 2040 b = SubElement(a, 'b') 2041 c = SubElement(a, 'c') 2042 d = SubElement(b, 'd') 2043 e = SubElement(c, 'e') 2044 2045 self.assertEqual( 2046 [b, d, c, e], 2047 list(a.iterdescendants())) 2048 self.assertEqual( 2049 [], 2050 list(d.iterdescendants()))
2051
2052 - def test_iterdescendants_tag(self):
2053 Element = self.etree.Element 2054 SubElement = self.etree.SubElement 2055 2056 a = Element('a') 2057 b = SubElement(a, 'b') 2058 c = SubElement(a, 'c') 2059 d = SubElement(b, 'd') 2060 e = SubElement(c, 'e') 2061 2062 self.assertEqual( 2063 [], 2064 list(a.iterdescendants('a'))) 2065 self.assertEqual( 2066 [], 2067 list(a.iterdescendants(tag='a'))) 2068 2069 a2 = SubElement(e, 'a') 2070 self.assertEqual( 2071 [a2], 2072 list(a.iterdescendants('a'))) 2073 2074 self.assertEqual( 2075 [a2], 2076 list(c.iterdescendants('a'))) 2077 self.assertEqual( 2078 [a2], 2079 list(c.iterdescendants(tag='a')))
2080
2081 - def test_iterdescendants_tag_multiple(self):
2082 Element = self.etree.Element 2083 SubElement = self.etree.SubElement 2084 2085 a = Element('a') 2086 b = SubElement(a, 'b') 2087 c = SubElement(a, 'c') 2088 d = SubElement(b, 'd') 2089 e = SubElement(c, 'e') 2090 2091 self.assertEqual( 2092 [b, e], 2093 list(a.iterdescendants(tag=('a', 'b', 'e')))) 2094 self.assertEqual( 2095 [b, e], 2096 list(a.iterdescendants('a', 'b', 'e'))) 2097 2098 a2 = SubElement(e, 'a') 2099 self.assertEqual( 2100 [b, a2], 2101 list(a.iterdescendants(tag=('a', 'b')))) 2102 self.assertEqual( 2103 [b, a2], 2104 list(a.iterdescendants('a', 'b'))) 2105 2106 self.assertEqual( 2107 [], 2108 list(c.iterdescendants(tag=('x', 'y', 'z')))) 2109 self.assertEqual( 2110 [], 2111 list(c.iterdescendants('x', 'y', 'z'))) 2112 2113 self.assertEqual( 2114 [b, d, c, e, a2], 2115 list(a.iterdescendants(tag=('x', 'y', 'z', '*')))) 2116 self.assertEqual( 2117 [b, d, c, e, a2], 2118 list(a.iterdescendants('x', 'y', 'z', '*')))
2119
2120 - def test_getroottree(self):
2121 Element = self.etree.Element 2122 SubElement = self.etree.SubElement 2123 2124 a = Element('a') 2125 b = SubElement(a, 'b') 2126 c = SubElement(a, 'c') 2127 d = SubElement(b, 'd') 2128 self.assertEqual( 2129 a, 2130 a.getroottree().getroot()) 2131 self.assertEqual( 2132 a, 2133 b.getroottree().getroot()) 2134 self.assertEqual( 2135 a, 2136 d.getroottree().getroot())
2137
2138 - def test_getnext(self):
2139 Element = self.etree.Element 2140 SubElement = self.etree.SubElement 2141 2142 a = Element('a') 2143 b = SubElement(a, 'b') 2144 c = SubElement(a, 'c') 2145 self.assertEqual( 2146 None, 2147 a.getnext()) 2148 self.assertEqual( 2149 c, 2150 b.getnext()) 2151 self.assertEqual( 2152 None, 2153 c.getnext())
2154
2155 - def test_getprevious(self):
2156 Element = self.etree.Element 2157 SubElement = self.etree.SubElement 2158 2159 a = Element('a') 2160 b = SubElement(a, 'b') 2161 c = SubElement(a, 'c') 2162 d = SubElement(b, 'd') 2163 self.assertEqual( 2164 None, 2165 a.getprevious()) 2166 self.assertEqual( 2167 b, 2168 c.getprevious()) 2169 self.assertEqual( 2170 None, 2171 b.getprevious())
2172
2173 - def test_itersiblings(self):
2174 Element = self.etree.Element 2175 SubElement = self.etree.SubElement 2176 2177 a = Element('a') 2178 b = SubElement(a, 'b') 2179 c = SubElement(a, 'c') 2180 d = SubElement(b, 'd') 2181 self.assertEqual( 2182 [], 2183 list(a.itersiblings())) 2184 self.assertEqual( 2185 [c], 2186 list(b.itersiblings())) 2187 self.assertEqual( 2188 [], 2189 list(c.itersiblings())) 2190 self.assertEqual( 2191 [b], 2192 list(c.itersiblings(preceding=True))) 2193 self.assertEqual( 2194 [], 2195 list(b.itersiblings(preceding=True)))
2196
2197 - def test_itersiblings_tag(self):
2198 Element = self.etree.Element 2199 SubElement = self.etree.SubElement 2200 2201 a = Element('a') 2202 b = SubElement(a, 'b') 2203 c = SubElement(a, 'c') 2204 d = SubElement(b, 'd') 2205 self.assertEqual( 2206 [], 2207 list(a.itersiblings(tag='XXX'))) 2208 self.assertEqual( 2209 [c], 2210 list(b.itersiblings(tag='c'))) 2211 self.assertEqual( 2212 [c], 2213 list(b.itersiblings(tag='*'))) 2214 self.assertEqual( 2215 [b], 2216 list(c.itersiblings(preceding=True, tag='b'))) 2217 self.assertEqual( 2218 [], 2219 list(c.itersiblings(preceding=True, tag='c')))
2220
2221 - def test_itersiblings_tag_multiple(self):
2222 Element = self.etree.Element 2223 SubElement = self.etree.SubElement 2224 2225 a = Element('a') 2226 b = SubElement(a, 'b') 2227 c = SubElement(a, 'c') 2228 d = SubElement(b, 'd') 2229 e = SubElement(a, 'e') 2230 self.assertEqual( 2231 [], 2232 list(a.itersiblings(tag=('XXX', 'YYY')))) 2233 self.assertEqual( 2234 [c, e], 2235 list(b.itersiblings(tag=('c', 'd', 'e')))) 2236 self.assertEqual( 2237 [b], 2238 list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd')))) 2239 self.assertEqual( 2240 [c, b], 2241 list(e.itersiblings(preceding=True, tag=('c', '*'))))
2242
2243 - def test_parseid(self):
2244 parseid = self.etree.parseid 2245 XML = self.etree.XML 2246 xml_text = _bytes(''' 2247 <!DOCTYPE document [ 2248 <!ELEMENT document (h1,p)*> 2249 <!ELEMENT h1 (#PCDATA)> 2250 <!ATTLIST h1 myid ID #REQUIRED> 2251 <!ELEMENT p (#PCDATA)> 2252 <!ATTLIST p someid ID #REQUIRED> 2253 ]> 2254 <document> 2255 <h1 myid="chapter1">...</h1> 2256 <p id="note1" class="note">...</p> 2257 <p>Regular paragraph.</p> 2258 <p xml:id="xmlid">XML:ID paragraph.</p> 2259 <p someid="warn1" class="warning">...</p> 2260 </document> 2261 ''') 2262 2263 tree, dic = parseid(BytesIO(xml_text)) 2264 root = tree.getroot() 2265 root2 = XML(xml_text) 2266 self.assertEqual(self._writeElement(root), 2267 self._writeElement(root2)) 2268 expected = { 2269 "chapter1" : root[0], 2270 "xmlid" : root[3], 2271 "warn1" : root[4] 2272 } 2273 self.assertTrue("chapter1" in dic) 2274 self.assertTrue("warn1" in dic) 2275 self.assertTrue("xmlid" in dic) 2276 self._checkIDDict(dic, expected)
2277
2278 - def test_XMLDTDID(self):
2279 XMLDTDID = self.etree.XMLDTDID 2280 XML = self.etree.XML 2281 xml_text = _bytes(''' 2282 <!DOCTYPE document [ 2283 <!ELEMENT document (h1,p)*> 2284 <!ELEMENT h1 (#PCDATA)> 2285 <!ATTLIST h1 myid ID #REQUIRED> 2286 <!ELEMENT p (#PCDATA)> 2287 <!ATTLIST p someid ID #REQUIRED> 2288 ]> 2289 <document> 2290 <h1 myid="chapter1">...</h1> 2291 <p id="note1" class="note">...</p> 2292 <p>Regular paragraph.</p> 2293 <p xml:id="xmlid">XML:ID paragraph.</p> 2294 <p someid="warn1" class="warning">...</p> 2295 </document> 2296 ''') 2297 2298 root, dic = XMLDTDID(xml_text) 2299 root2 = XML(xml_text) 2300 self.assertEqual(self._writeElement(root), 2301 self._writeElement(root2)) 2302 expected = { 2303 "chapter1" : root[0], 2304 "xmlid" : root[3], 2305 "warn1" : root[4] 2306 } 2307 self.assertTrue("chapter1" in dic) 2308 self.assertTrue("warn1" in dic) 2309 self.assertTrue("xmlid" in dic) 2310 self._checkIDDict(dic, expected)
2311
2312 - def test_XMLDTDID_empty(self):
2313 XMLDTDID = self.etree.XMLDTDID 2314 XML = self.etree.XML 2315 xml_text = _bytes(''' 2316 <document> 2317 <h1 myid="chapter1">...</h1> 2318 <p id="note1" class="note">...</p> 2319 <p>Regular paragraph.</p> 2320 <p someid="warn1" class="warning">...</p> 2321 </document> 2322 ''') 2323 2324 root, dic = XMLDTDID(xml_text) 2325 root2 = XML(xml_text) 2326 self.assertEqual(self._writeElement(root), 2327 self._writeElement(root2)) 2328 expected = {} 2329 self._checkIDDict(dic, expected)
2330
2331 - def test_XMLDTDID_no_id_dict(self):
2332 XMLDTDID = self.etree.XMLDTDID 2333 XML = self.etree.XML 2334 xml_text = _bytes(''' 2335 <!DOCTYPE document [ 2336 <!ELEMENT document (h1,p)*> 2337 <!ELEMENT h1 (#PCDATA)> 2338 <!ATTLIST h1 myid ID #REQUIRED> 2339 <!ELEMENT p (#PCDATA)> 2340 <!ATTLIST p someid ID #REQUIRED> 2341 ]> 2342 <document> 2343 <h1 myid="chapter1">...</h1> 2344 <p id="note1" class="note">...</p> 2345 <p>Regular paragraph.</p> 2346 <p xml:id="xmlid">XML:ID paragraph.</p> 2347 <p someid="warn1" class="warning">...</p> 2348 </document> 2349 ''') 2350 2351 parser = etree.XMLParser(collect_ids=False) 2352 root, dic = XMLDTDID(xml_text, parser=parser) 2353 root2 = XML(xml_text) 2354 self.assertEqual(self._writeElement(root), 2355 self._writeElement(root2)) 2356 self.assertFalse(dic) 2357 self._checkIDDict(dic, {})
2358
2359 - def _checkIDDict(self, dic, expected):
2360 self.assertEqual(len(dic), 2361 len(expected)) 2362 self.assertEqual(sorted(dic.items()), 2363 sorted(expected.items())) 2364 if sys.version_info < (3,): 2365 self.assertEqual(sorted(dic.iteritems()), 2366 sorted(expected.iteritems())) 2367 self.assertEqual(sorted(dic.keys()), 2368 sorted(expected.keys())) 2369 if sys.version_info < (3,): 2370 self.assertEqual(sorted(dic.iterkeys()), 2371 sorted(expected.iterkeys())) 2372 if sys.version_info < (3,): 2373 self.assertEqual(sorted(dic.values()), 2374 sorted(expected.values())) 2375 self.assertEqual(sorted(dic.itervalues()), 2376 sorted(expected.itervalues()))
2377
2378 - def test_namespaces(self):
2379 etree = self.etree 2380 2381 r = {'foo': 'http://ns.infrae.com/foo'} 2382 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2383 self.assertEqual( 2384 'foo', 2385 e.prefix) 2386 self.assertEqual( 2387 _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'), 2388 self._writeElement(e))
2389
2390 - def test_namespaces_default(self):
2391 etree = self.etree 2392 2393 r = {None: 'http://ns.infrae.com/foo'} 2394 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2395 self.assertEqual( 2396 None, 2397 e.prefix) 2398 self.assertEqual( 2399 '{http://ns.infrae.com/foo}bar', 2400 e.tag) 2401 self.assertEqual( 2402 _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'), 2403 self._writeElement(e))
2404
2405 - def test_namespaces_default_and_attr(self):
2406 etree = self.etree 2407 2408 r = {None: 'http://ns.infrae.com/foo', 2409 'hoi': 'http://ns.infrae.com/hoi'} 2410 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2411 e.set('{http://ns.infrae.com/hoi}test', 'value') 2412 self.assertEqual( 2413 _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'), 2414 self._writeElement(e))
2415
2416 - def test_attribute_keeps_namespace_prefix_on_merge(self):
2417 etree = self.etree 2418 2419 root = etree.Element('{http://test/ns}root', 2420 nsmap={None: 'http://test/ns'}) 2421 sub = etree.Element('{http://test/ns}sub', 2422 nsmap={'test': 'http://test/ns'}) 2423 2424 sub.attrib['{http://test/ns}attr'] = 'value' 2425 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2426 self.assertEqual( 2427 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 2428 etree.tostring(sub)) 2429 2430 root.append(sub) 2431 self.assertEqual( 2432 _bytes('<root xmlns="http://test/ns">' 2433 '<sub xmlns:test="http://test/ns" test:attr="value"/>' 2434 '</root>'), 2435 etree.tostring(root))
2436
2437 - def test_attribute_keeps_namespace_prefix_on_merge_with_nons(self):
2438 etree = self.etree 2439 2440 root = etree.Element('root') 2441 sub = etree.Element('{http://test/ns}sub', 2442 nsmap={'test': 'http://test/ns'}) 2443 2444 sub.attrib['{http://test/ns}attr'] = 'value' 2445 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2446 self.assertEqual( 2447 _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 2448 etree.tostring(sub)) 2449 2450 root.append(sub) 2451 self.assertEqual( 2452 _bytes('<root>' 2453 '<test:sub xmlns:test="http://test/ns" test:attr="value"/>' 2454 '</root>'), 2455 etree.tostring(root))
2456
2457 - def test_attribute_gets_namespace_prefix_on_merge_with_nons(self):
2458 etree = self.etree 2459 2460 root = etree.Element('root') 2461 sub = etree.Element('{http://test/ns}sub', 2462 nsmap={None: 'http://test/ns'}) 2463 2464 sub.attrib['{http://test/ns}attr'] = 'value' 2465 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2466 self.assertEqual( 2467 _bytes('<sub xmlns="http://test/ns" ' 2468 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 2469 etree.tostring(sub)) 2470 2471 root.append(sub) 2472 self.assertEqual( 2473 _bytes('<root>' 2474 '<sub xmlns="http://test/ns"' 2475 ' xmlns:ns0="http://test/ns" ns0:attr="value"/>' 2476 '</root>'), 2477 etree.tostring(root))
2478
2479 - def test_attribute_gets_namespace_prefix_on_merge(self):
2480 etree = self.etree 2481 2482 root = etree.Element('{http://test/ns}root', 2483 nsmap={'test': 'http://test/ns', 2484 None: 'http://test/ns'}) 2485 sub = etree.Element('{http://test/ns}sub', 2486 nsmap={None: 'http://test/ns'}) 2487 2488 sub.attrib['{http://test/ns}attr'] = 'value' 2489 self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 2490 self.assertEqual( 2491 _bytes('<sub xmlns="http://test/ns" ' 2492 'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 2493 etree.tostring(sub)) 2494 2495 root.append(sub) 2496 self.assertEqual( 2497 _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">' 2498 '<test:sub test:attr="value"/>' 2499 '</test:root>'), 2500 etree.tostring(root))
2501
2502 - def test_namespaces_elementtree(self):
2503 etree = self.etree 2504 r = {None: 'http://ns.infrae.com/foo', 2505 'hoi': 'http://ns.infrae.com/hoi'} 2506 e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 2507 tree = etree.ElementTree(element=e) 2508 etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 2509 self.assertEqual( 2510 _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'), 2511 self._writeElement(e))
2512
2513 - def test_namespaces_default_copy_element(self):
2514 etree = self.etree 2515 2516 r = {None: 'http://ns.infrae.com/foo'} 2517 e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2518 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2519 2520 e1.append(e2) 2521 2522 self.assertEqual( 2523 None, 2524 e1.prefix) 2525 self.assertEqual( 2526 None, 2527 e1[0].prefix) 2528 self.assertEqual( 2529 '{http://ns.infrae.com/foo}bar', 2530 e1.tag) 2531 self.assertEqual( 2532 '{http://ns.infrae.com/foo}bar', 2533 e1[0].tag)
2534
2535 - def test_namespaces_copy_element(self):
2536 etree = self.etree 2537 2538 r = {None: 'http://ns.infrae.com/BAR'} 2539 e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 2540 e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2541 2542 e1.append(e2) 2543 2544 self.assertEqual( 2545 None, 2546 e1.prefix) 2547 self.assertNotEqual( 2548 None, 2549 e2.prefix) 2550 self.assertEqual( 2551 '{http://ns.infrae.com/BAR}bar', 2552 e1.tag) 2553 self.assertEqual( 2554 '{http://ns.infrae.com/foo}bar', 2555 e2.tag)
2556
2557 - def test_namespaces_reuse_after_move(self):
2558 ns_href = "http://a.b.c" 2559 one = self.etree.fromstring( 2560 _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 2561 baz = one[0][0] 2562 2563 two = self.etree.fromstring( 2564 _bytes('<root xmlns:ns="%s"/>' % ns_href)) 2565 two.append(baz) 2566 del one # make sure the source document is deallocated 2567 2568 self.assertEqual('{%s}baz' % ns_href, baz.tag) 2569 self.assertEqual( 2570 _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href), 2571 self.etree.tostring(two))
2572
2573 - def test_namespace_cleanup(self):
2574 xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>') 2575 root = self.etree.fromstring(xml) 2576 self.assertEqual(xml, 2577 self.etree.tostring(root)) 2578 self.etree.cleanup_namespaces(root) 2579 self.assertEqual( 2580 _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'), 2581 self.etree.tostring(root))
2582
2583 - def test_element_nsmap(self):
2584 etree = self.etree 2585 2586 r = {None: 'http://ns.infrae.com/foo', 2587 'hoi': 'http://ns.infrae.com/hoi'} 2588 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 2589 self.assertEqual( 2590 r, 2591 e.nsmap)
2592
2593 - def test_subelement_nsmap(self):
2594 etree = self.etree 2595 2596 re = {None: 'http://ns.infrae.com/foo', 2597 'hoi': 'http://ns.infrae.com/hoi'} 2598 e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re) 2599 2600 rs = {None: 'http://ns.infrae.com/honk', 2601 'top': 'http://ns.infrae.com/top'} 2602 s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs) 2603 2604 r = re.copy() 2605 r.update(rs) 2606 self.assertEqual(re, e.nsmap) 2607 self.assertEqual(r, s.nsmap)
2608
2609 - def test_html_prefix_nsmap(self):
2610 etree = self.etree 2611 el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description') 2612 self.assertEqual({'hha': None}, el.nsmap)
2613
2614 - def test_getiterator_filter_multiple(self):
2615 Element = self.etree.Element 2616 SubElement = self.etree.SubElement 2617 2618 a = Element('a') 2619 b = SubElement(a, 'b') 2620 c = SubElement(a, 'c') 2621 d = SubElement(b, 'd') 2622 e = SubElement(c, 'e') 2623 f = SubElement(c, 'f') 2624 2625 self.assertEqual( 2626 [a, b], 2627 list(a.getiterator('a', 'b'))) 2628 self.assertEqual( 2629 [], 2630 list(a.getiterator('x', 'y'))) 2631 self.assertEqual( 2632 [a, f], 2633 list(a.getiterator('f', 'a'))) 2634 self.assertEqual( 2635 [c, e, f], 2636 list(c.getiterator('c', '*', 'a'))) 2637 self.assertEqual( 2638 [], 2639 list(a.getiterator( (), () )))
2640
2641 - def test_getiterator_filter_multiple_tuple(self):
2642 Element = self.etree.Element 2643 SubElement = self.etree.SubElement 2644 2645 a = Element('a') 2646 b = SubElement(a, 'b') 2647 c = SubElement(a, 'c') 2648 d = SubElement(b, 'd') 2649 e = SubElement(c, 'e') 2650 f = SubElement(c, 'f') 2651 2652 self.assertEqual( 2653 [a, b], 2654 list(a.getiterator( ('a', 'b') ))) 2655 self.assertEqual( 2656 [], 2657 list(a.getiterator( ('x', 'y') ))) 2658 self.assertEqual( 2659 [a, f], 2660 list(a.getiterator( ('f', 'a') ))) 2661 self.assertEqual( 2662 [c, e, f], 2663 list(c.getiterator( ('c', '*', 'a') ))) 2664 self.assertEqual( 2665 [], 2666 list(a.getiterator( () )))
2667
2668 - def test_getiterator_filter_namespace(self):
2669 Element = self.etree.Element 2670 SubElement = self.etree.SubElement 2671 2672 a = Element('{a}a') 2673 b = SubElement(a, '{a}b') 2674 c = SubElement(a, '{a}c') 2675 d = SubElement(b, '{b}d') 2676 e = SubElement(c, '{a}e') 2677 f = SubElement(c, '{b}f') 2678 g = SubElement(c, 'g') 2679 2680 self.assertEqual( 2681 [a], 2682 list(a.getiterator('{a}a'))) 2683 self.assertEqual( 2684 [], 2685 list(a.getiterator('{b}a'))) 2686 self.assertEqual( 2687 [], 2688 list(a.getiterator('a'))) 2689 self.assertEqual( 2690 [a,b,d,c,e,f,g], 2691 list(a.getiterator('*'))) 2692 self.assertEqual( 2693 [f], 2694 list(c.getiterator('{b}*'))) 2695 self.assertEqual( 2696 [d, f], 2697 list(a.getiterator('{b}*'))) 2698 self.assertEqual( 2699 [g], 2700 list(a.getiterator('g'))) 2701 self.assertEqual( 2702 [g], 2703 list(a.getiterator('{}g'))) 2704 self.assertEqual( 2705 [g], 2706 list(a.getiterator('{}*')))
2707
2708 - def test_getiterator_filter_local_name(self):
2709 Element = self.etree.Element 2710 SubElement = self.etree.SubElement 2711 2712 a = Element('{a}a') 2713 b = SubElement(a, '{nsA}b') 2714 c = SubElement(b, '{nsB}b') 2715 d = SubElement(a, 'b') 2716 e = SubElement(a, '{nsA}e') 2717 f = SubElement(e, '{nsB}e') 2718 g = SubElement(e, 'e') 2719 2720 self.assertEqual( 2721 [b, c, d], 2722 list(a.getiterator('{*}b'))) 2723 self.assertEqual( 2724 [e, f, g], 2725 list(a.getiterator('{*}e'))) 2726 self.assertEqual( 2727 [a, b, c, d, e, f, g], 2728 list(a.getiterator('{*}*')))
2729
2730 - def test_getiterator_filter_entities(self):
2731 Element = self.etree.Element 2732 Entity = self.etree.Entity 2733 SubElement = self.etree.SubElement 2734 2735 a = Element('a') 2736 b = SubElement(a, 'b') 2737 entity_b = Entity("TEST-b") 2738 b.append(entity_b) 2739 2740 self.assertEqual( 2741 [entity_b], 2742 list(a.getiterator(Entity))) 2743 2744 entity_a = Entity("TEST-a") 2745 a.append(entity_a) 2746 2747 self.assertEqual( 2748 [entity_b, entity_a], 2749 list(a.getiterator(Entity))) 2750 2751 self.assertEqual( 2752 [entity_b], 2753 list(b.getiterator(Entity)))
2754
2755 - def test_getiterator_filter_element(self):
2756 Element = self.etree.Element 2757 Comment = self.etree.Comment 2758 PI = self.etree.PI 2759 SubElement = self.etree.SubElement 2760 2761 a = Element('a') 2762 b = SubElement(a, 'b') 2763 a.append(Comment("test")) 2764 a.append(PI("pi", "content")) 2765 c = SubElement(a, 'c') 2766 2767 self.assertEqual( 2768 [a, b, c], 2769 list(a.getiterator(Element)))
2770
2771 - def test_getiterator_filter_all_comment_pi(self):
2772 # ElementTree iterates over everything here 2773 Element = self.etree.Element 2774 Comment = self.etree.Comment 2775 PI = self.etree.PI 2776 SubElement = self.etree.SubElement 2777 2778 a = Element('a') 2779 b = SubElement(a, 'b') 2780 a.append(Comment("test")) 2781 a.append(PI("pi", "content")) 2782 c = SubElement(a, 'c') 2783 2784 self.assertEqual( 2785 [a, b, c], 2786 list(a.getiterator('*')))
2787
2788 - def test_elementtree_getelementpath(self):
2789 a = etree.Element("a") 2790 b = etree.SubElement(a, "b") 2791 c = etree.SubElement(a, "c") 2792 d1 = etree.SubElement(c, "d") 2793 d2 = etree.SubElement(c, "d") 2794 c.text = d1.text = 'TEXT' 2795 2796 tree = etree.ElementTree(a) 2797 self.assertEqual('.', tree.getelementpath(a)) 2798 self.assertEqual('c/d[1]', tree.getelementpath(d1)) 2799 self.assertEqual('c/d[2]', tree.getelementpath(d2)) 2800 2801 self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 2802 self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 2803 2804 tree = etree.ElementTree(c) 2805 self.assertEqual('.', tree.getelementpath(c)) 2806 self.assertEqual('d[2]', tree.getelementpath(d2)) 2807 self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 2808 2809 tree = etree.ElementTree(b) # not a parent of a/c/d1/d2 2810 self.assertEqual('.', tree.getelementpath(b)) 2811 self.assertRaises(ValueError, tree.getelementpath, a) 2812 self.assertRaises(ValueError, tree.getelementpath, c) 2813 self.assertRaises(ValueError, tree.getelementpath, d2)
2814
2815 - def test_elementtree_getelementpath_ns(self):
2816 a = etree.Element("{http://ns1/}a") 2817 b = etree.SubElement(a, "{http://ns1/}b") 2818 c = etree.SubElement(a, "{http://ns1/}c") 2819 d1 = etree.SubElement(c, "{http://ns1/}d") 2820 d2 = etree.SubElement(c, "{http://ns2/}d") 2821 d3 = etree.SubElement(c, "{http://ns1/}d") 2822 2823 tree = etree.ElementTree(a) 2824 self.assertEqual('.', tree.getelementpath(a)) 2825 self.assertEqual('{http://ns1/}c/{http://ns1/}d[1]', 2826 tree.getelementpath(d1)) 2827 self.assertEqual('{http://ns1/}c/{http://ns2/}d', 2828 tree.getelementpath(d2)) 2829 self.assertEqual('{http://ns1/}c/{http://ns1/}d[2]', 2830 tree.getelementpath(d3)) 2831 2832 self.assertEqual(a, tree.find(tree.getelementpath(a))) 2833 self.assertEqual(b, tree.find(tree.getelementpath(b))) 2834 self.assertEqual(c, tree.find(tree.getelementpath(c))) 2835 self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 2836 self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 2837 self.assertEqual(d3, tree.find(tree.getelementpath(d3))) 2838 2839 tree = etree.ElementTree(c) 2840 self.assertEqual('{http://ns1/}d[1]', tree.getelementpath(d1)) 2841 self.assertEqual('{http://ns2/}d', tree.getelementpath(d2)) 2842 self.assertEqual('{http://ns1/}d[2]', tree.getelementpath(d3)) 2843 self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 2844 self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 2845 self.assertEqual(d3, tree.find(tree.getelementpath(d3))) 2846 2847 tree = etree.ElementTree(b) # not a parent of d1/d2 2848 self.assertRaises(ValueError, tree.getelementpath, d1) 2849 self.assertRaises(ValueError, tree.getelementpath, d2)
2850
2851 - def test_elementtree_find_qname(self):
2852 XML = self.etree.XML 2853 ElementTree = self.etree.ElementTree 2854 QName = self.etree.QName 2855 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 2856 self.assertEqual(tree.find(QName("c")), tree.getroot()[2])
2857
2858 - def test_elementtree_findall_qname(self):
2859 XML = self.etree.XML 2860 ElementTree = self.etree.ElementTree 2861 QName = self.etree.QName 2862 tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 2863 self.assertEqual(len(list(tree.findall(QName("c")))), 1)
2864
2865 - def test_elementtree_findall_ns_qname(self):
2866 XML = self.etree.XML 2867 ElementTree = self.etree.ElementTree 2868 QName = self.etree.QName 2869 tree = ElementTree(XML( 2870 _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))) 2871 self.assertEqual(len(list(tree.findall(QName("b")))), 2) 2872 self.assertEqual(len(list(tree.findall(QName("X", "b")))), 1)
2873
2874 - def test_findall_ns(self):
2875 XML = self.etree.XML 2876 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')) 2877 self.assertEqual(len(root.findall(".//{X}b")), 2) 2878 self.assertEqual(len(root.findall(".//{X}*")), 2) 2879 self.assertEqual(len(root.findall(".//b")), 3)
2880
2881 - def test_findall_different_nsmaps(self):
2882 XML = self.etree.XML 2883 root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>')) 2884 nsmap = {'xx': 'X'} 2885 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) 2886 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2) 2887 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2) 2888 nsmap = {'xx': 'Y'} 2889 self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1) 2890 self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1) 2891 self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2)
2892
2893 - def test_findall_syntax_error(self):
2894 XML = self.etree.XML 2895 root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>')) 2896 self.assertRaises(SyntaxError, root.findall, '') 2897 self.assertRaises(SyntaxError, root.findall, '//') # absolute path on Element 2898 self.assertRaises(SyntaxError, root.findall, './//')
2899
2900 - def test_index(self):
2901 etree = self.etree 2902 e = etree.Element('foo') 2903 for i in range(10): 2904 etree.SubElement(e, 'a%s' % i) 2905 for i in range(10): 2906 self.assertEqual( 2907 i, 2908 e.index(e[i])) 2909 self.assertEqual( 2910 3, e.index(e[3], 3)) 2911 self.assertRaises( 2912 ValueError, e.index, e[3], 4) 2913 self.assertRaises( 2914 ValueError, e.index, e[3], 0, 2) 2915 self.assertRaises( 2916 ValueError, e.index, e[8], 0, -3) 2917 self.assertRaises( 2918 ValueError, e.index, e[8], -5, -3) 2919 self.assertEqual( 2920 8, e.index(e[8], 0, -1)) 2921 self.assertEqual( 2922 8, e.index(e[8], -12, -1)) 2923 self.assertEqual( 2924 0, e.index(e[0], -12, -1))
2925
2926 - def test_replace(self):
2927 etree = self.etree 2928 e = etree.Element('foo') 2929 for i in range(10): 2930 el = etree.SubElement(e, 'a%s' % i) 2931 el.text = "text%d" % i 2932 el.tail = "tail%d" % i 2933 2934 child0 = e[0] 2935 child1 = e[1] 2936 child2 = e[2] 2937 2938 e.replace(e[0], e[1]) 2939 self.assertEqual( 2940 9, len(e)) 2941 self.assertEqual( 2942 child1, e[0]) 2943 self.assertEqual( 2944 child1.text, "text1") 2945 self.assertEqual( 2946 child1.tail, "tail1") 2947 self.assertEqual( 2948 child0.tail, "tail0") 2949 self.assertEqual( 2950 child2, e[1]) 2951 2952 e.replace(e[-1], e[0]) 2953 self.assertEqual( 2954 child1, e[-1]) 2955 self.assertEqual( 2956 child1.text, "text1") 2957 self.assertEqual( 2958 child1.tail, "tail1") 2959 self.assertEqual( 2960 child2, e[0])
2961
2962 - def test_replace_new(self):
2963 etree = self.etree 2964 e = etree.Element('foo') 2965 for i in range(10): 2966 etree.SubElement(e, 'a%s' % i) 2967 2968 new_element = etree.Element("test") 2969 new_element.text = "TESTTEXT" 2970 new_element.tail = "TESTTAIL" 2971 child1 = e[1] 2972 e.replace(e[0], new_element) 2973 self.assertEqual( 2974 new_element, e[0]) 2975 self.assertEqual( 2976 "TESTTEXT", 2977 e[0].text) 2978 self.assertEqual( 2979 "TESTTAIL", 2980 e[0].tail) 2981 self.assertEqual( 2982 child1, e[1])
2983
2984 - def test_setslice_all_empty_reversed(self):
2985 Element = self.etree.Element 2986 SubElement = self.etree.SubElement 2987 2988 a = Element('a') 2989 2990 e = Element('e') 2991 f = Element('f') 2992 g = Element('g') 2993 2994 s = [e, f, g] 2995 a[::-1] = s 2996 self.assertEqual( 2997 [g, f, e], 2998 list(a))
2999
3000 - def test_setslice_step(self):
3001 Element = self.etree.Element 3002 SubElement = self.etree.SubElement 3003 3004 a = Element('a') 3005 b = SubElement(a, 'b') 3006 c = SubElement(a, 'c') 3007 d = SubElement(a, 'd') 3008 e = SubElement(a, 'e') 3009 3010 x = Element('x') 3011 y = Element('y') 3012 3013 a[1::2] = [x, y] 3014 self.assertEqual( 3015 [b, x, d, y], 3016 list(a))
3017
3018 - def test_setslice_step_negative(self):
3019 Element = self.etree.Element 3020 SubElement = self.etree.SubElement 3021 3022 a = Element('a') 3023 b = SubElement(a, 'b') 3024 c = SubElement(a, 'c') 3025 d = SubElement(a, 'd') 3026 e = SubElement(a, 'e') 3027 3028 x = Element('x') 3029 y = Element('y') 3030 3031 a[1::-1] = [x, y] 3032 self.assertEqual( 3033 [y, x, d, e], 3034 list(a))
3035
3036 - def test_setslice_step_negative2(self):
3037 Element = self.etree.Element 3038 SubElement = self.etree.SubElement 3039 3040 a = Element('a') 3041 b = SubElement(a, 'b') 3042 c = SubElement(a, 'c') 3043 d = SubElement(a, 'd') 3044 e = SubElement(a, 'e') 3045 3046 x = Element('x') 3047 y = Element('y') 3048 3049 a[::-2] = [x, y] 3050 self.assertEqual( 3051 [b, y, d, x], 3052 list(a))
3053
3054 - def test_setslice_step_overrun(self):
3055 Element = self.etree.Element 3056 SubElement = self.etree.SubElement 3057 try: 3058 slice 3059 except NameError: 3060 print("slice() not found") 3061 return 3062 3063 a = Element('a') 3064 b = SubElement(a, 'b') 3065 c = SubElement(a, 'c') 3066 d = SubElement(a, 'd') 3067 e = SubElement(a, 'e') 3068 3069 x = Element('x') 3070 y = Element('y') 3071 z = Element('z') 3072 3073 self.assertRaises( 3074 ValueError, 3075 operator.setitem, a, slice(1,None,2), [x, y, z]) 3076 3077 self.assertEqual( 3078 [b, c, d, e], 3079 list(a))
3080
3081 - def test_sourceline_XML(self):
3082 XML = self.etree.XML 3083 root = XML(_bytes('''<?xml version="1.0"?> 3084 <root><test> 3085 3086 <bla/></test> 3087 </root> 3088 ''')) 3089 3090 self.assertEqual( 3091 [2, 2, 4], 3092 [ el.sourceline for el in root.getiterator() ])
3093
3094 - def test_large_sourceline_XML(self):
3095 XML = self.etree.XML 3096 root = XML(_bytes( 3097 '<?xml version="1.0"?>\n' 3098 '<root>' + '\n' * 65536 + 3099 '<p>' + '\n' * 65536 + '</p>\n' + 3100 '<br/>\n' 3101 '</root>')) 3102 3103 if self.etree.LIBXML_VERSION >= (2, 9): 3104 expected = [2, 131074, 131076] 3105 else: 3106 expected = [2, 65535, 65535] 3107 3108 self.assertEqual(expected, [el.sourceline for el in root.iter()])
3109
3110 - def test_sourceline_parse(self):
3111 parse = self.etree.parse 3112 tree = parse(fileInTestDir('include/test_xinclude.xml')) 3113 3114 self.assertEqual( 3115 [1, 2, 3], 3116 [ el.sourceline for el in tree.getiterator() ])
3117
3118 - def test_sourceline_iterparse_end(self):
3119 iterparse = self.etree.iterparse 3120 lines = [ el.sourceline for (event, el) in 3121 iterparse(fileInTestDir('include/test_xinclude.xml')) ] 3122 3123 self.assertEqual( 3124 [2, 3, 1], 3125 lines)
3126
3127 - def test_sourceline_iterparse_start(self):
3128 iterparse = self.etree.iterparse 3129 lines = [ el.sourceline for (event, el) in 3130 iterparse(fileInTestDir('include/test_xinclude.xml'), 3131 events=("start",)) ] 3132 3133 self.assertEqual( 3134 [1, 2, 3], 3135 lines)
3136
3137 - def test_sourceline_element(self):
3138 Element = self.etree.Element 3139 SubElement = self.etree.SubElement 3140 el = Element("test") 3141 self.assertEqual(None, el.sourceline) 3142 3143 child = SubElement(el, "test") 3144 self.assertEqual(None, el.sourceline) 3145 self.assertEqual(None, child.sourceline)
3146
3147 - def test_XML_base_url_docinfo(self):
3148 etree = self.etree 3149 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3150 docinfo = root.getroottree().docinfo 3151 self.assertEqual(docinfo.URL, "http://no/such/url")
3152
3153 - def test_XML_set_base_url_docinfo(self):
3154 etree = self.etree 3155 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3156 docinfo = root.getroottree().docinfo 3157 self.assertEqual(docinfo.URL, "http://no/such/url") 3158 docinfo.URL = "https://secret/url" 3159 self.assertEqual(docinfo.URL, "https://secret/url")
3160
3161 - def test_parse_stringio_base_url(self):
3162 etree = self.etree 3163 tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url") 3164 docinfo = tree.docinfo 3165 self.assertEqual(docinfo.URL, "http://no/such/url")
3166
3167 - def test_parse_base_url_docinfo(self):
3168 etree = self.etree 3169 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 3170 base_url="http://no/such/url") 3171 docinfo = tree.docinfo 3172 self.assertEqual(docinfo.URL, "http://no/such/url")
3173
3174 - def test_HTML_base_url_docinfo(self):
3175 etree = self.etree 3176 root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url") 3177 docinfo = root.getroottree().docinfo 3178 self.assertEqual(docinfo.URL, "http://no/such/url")
3179
3180 - def test_docinfo_public(self):
3181 etree = self.etree 3182 xml_header = '<?xml version="1.0" encoding="ascii"?>' 3183 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 3184 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 3185 doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id) 3186 3187 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 3188 3189 tree = etree.parse(BytesIO(xml)) 3190 docinfo = tree.docinfo 3191 self.assertEqual(docinfo.encoding, "ascii") 3192 self.assertEqual(docinfo.xml_version, "1.0") 3193 self.assertEqual(docinfo.public_id, pub_id) 3194 self.assertEqual(docinfo.system_url, sys_id) 3195 self.assertEqual(docinfo.root_name, 'html') 3196 self.assertEqual(docinfo.doctype, doctype_string)
3197
3198 - def test_docinfo_system(self):
3199 etree = self.etree 3200 xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 3201 sys_id = "some.dtd" 3202 doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 3203 xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 3204 3205 tree = etree.parse(BytesIO(xml)) 3206 docinfo = tree.docinfo 3207 self.assertEqual(docinfo.encoding, "UTF-8") 3208 self.assertEqual(docinfo.xml_version, "1.0") 3209 self.assertEqual(docinfo.public_id, None) 3210 self.assertEqual(docinfo.system_url, sys_id) 3211 self.assertEqual(docinfo.root_name, 'html') 3212 self.assertEqual(docinfo.doctype, doctype_string)
3213
3214 - def test_docinfo_empty(self):
3215 etree = self.etree 3216 xml = _bytes('<html><body></body></html>') 3217 tree = etree.parse(BytesIO(xml)) 3218 docinfo = tree.docinfo 3219 self.assertEqual(docinfo.encoding, "UTF-8") 3220 self.assertEqual(docinfo.xml_version, "1.0") 3221 self.assertEqual(docinfo.public_id, None) 3222 self.assertEqual(docinfo.system_url, None) 3223 self.assertEqual(docinfo.root_name, 'html') 3224 self.assertEqual(docinfo.doctype, '')
3225
3226 - def test_docinfo_name_only(self):
3227 etree = self.etree 3228 xml = _bytes('<!DOCTYPE root><root></root>') 3229 tree = etree.parse(BytesIO(xml)) 3230 docinfo = tree.docinfo 3231 self.assertEqual(docinfo.encoding, "UTF-8") 3232 self.assertEqual(docinfo.xml_version, "1.0") 3233 self.assertEqual(docinfo.public_id, None) 3234 self.assertEqual(docinfo.system_url, None) 3235 self.assertEqual(docinfo.root_name, 'root') 3236 self.assertEqual(docinfo.doctype, '<!DOCTYPE root>')
3237
3238 - def test_doctype_name_only_roundtrip(self):
3239 etree = self.etree 3240 xml = _bytes('<!DOCTYPE root>\n<root/>') 3241 tree = etree.parse(BytesIO(xml)) 3242 self.assertEqual(xml, etree.tostring(tree))
3243
3244 - def test_doctype_output_override(self):
3245 etree = self.etree 3246 pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 3247 sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 3248 doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)) 3249 3250 xml = _bytes('<!DOCTYPE root>\n<root/>') 3251 tree = etree.parse(BytesIO(xml)) 3252 self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string), 3253 etree.tostring(tree, doctype=doctype_string))
3254
3255 - def test_xml_base(self):
3256 etree = self.etree 3257 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3258 self.assertEqual(root.base, "http://no/such/url") 3259 self.assertEqual( 3260 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 3261 root.base = "https://secret/url" 3262 self.assertEqual(root.base, "https://secret/url") 3263 self.assertEqual( 3264 root.get('{http://www.w3.org/XML/1998/namespace}base'), 3265 "https://secret/url")
3266
3267 - def test_xml_base_attribute(self):
3268 etree = self.etree 3269 root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 3270 self.assertEqual(root.base, "http://no/such/url") 3271 self.assertEqual( 3272 root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 3273 root.set('{http://www.w3.org/XML/1998/namespace}base', 3274 "https://secret/url") 3275 self.assertEqual(root.base, "https://secret/url") 3276 self.assertEqual( 3277 root.get('{http://www.w3.org/XML/1998/namespace}base'), 3278 "https://secret/url")
3279
3280 - def test_html_base(self):
3281 etree = self.etree 3282 root = etree.HTML(_bytes("<html><body></body></html>"), 3283 base_url="http://no/such/url") 3284 self.assertEqual(root.base, "http://no/such/url")
3285
3286 - def test_html_base_tag(self):
3287 etree = self.etree 3288 root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>')) 3289 self.assertEqual(root.base, "http://no/such/url")
3290
3291 - def test_parse_fileobject_unicode(self):
3292 # parse from a file object that returns unicode strings 3293 f = LargeFileLikeUnicode() 3294 tree = self.etree.parse(f) 3295 root = tree.getroot() 3296 self.assertTrue(root.tag.endswith('root'))
3297
3298 - def test_dtd_io(self):
3299 # check that DTDs that go in also go back out 3300 xml = _bytes('''\ 3301 <!DOCTYPE test SYSTEM "test.dtd" [ 3302 <!ENTITY entity "tasty"> 3303 <!ELEMENT test (a)> 3304 <!ELEMENT a (#PCDATA)> 3305 ]> 3306 <test><a>test-test</a></test>\ 3307 ''') 3308 tree = self.etree.parse(BytesIO(xml)) 3309 self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")), 3310 xml.replace(_bytes(" "), _bytes("")))
3311
3312 - def test_byte_zero(self):
3313 Element = self.etree.Element 3314 3315 a = Element('a') 3316 self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho') 3317 self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho') 3318 3319 self.assertRaises(ValueError, Element, 'ha\0ho')
3320
3321 - def test_unicode_byte_zero(self):
3322 Element = self.etree.Element 3323 3324 a = Element('a') 3325 self.assertRaises(ValueError, setattr, a, "text", 3326 _str('ha\0ho')) 3327 self.assertRaises(ValueError, setattr, a, "tail", 3328 _str('ha\0ho')) 3329 3330 self.assertRaises(ValueError, Element, 3331 _str('ha\0ho'))
3332
3333 - def test_byte_invalid(self):
3334 Element = self.etree.Element 3335 3336 a = Element('a') 3337 self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho') 3338 self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho') 3339 3340 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho') 3341 self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho') 3342 3343 self.assertRaises(ValueError, Element, 'ha\x07ho') 3344 self.assertRaises(ValueError, Element, 'ha\x02ho')
3345
3346 - def test_unicode_byte_invalid(self):
3347 Element = self.etree.Element 3348 3349 a = Element('a') 3350 self.assertRaises(ValueError, setattr, a, "text", 3351 _str('ha\x07ho')) 3352 self.assertRaises(ValueError, setattr, a, "text", 3353 _str('ha\x02ho')) 3354 3355 self.assertRaises(ValueError, setattr, a, "tail", 3356 _str('ha\x07ho')) 3357 self.assertRaises(ValueError, setattr, a, "tail", 3358 _str('ha\x02ho')) 3359 3360 self.assertRaises(ValueError, Element, 3361 _str('ha\x07ho')) 3362 self.assertRaises(ValueError, Element, 3363 _str('ha\x02ho'))
3364
3365 - def test_unicode_byte_invalid_sequence(self):
3366 Element = self.etree.Element 3367 3368 a = Element('a') 3369 self.assertRaises(ValueError, setattr, a, "text", 3370 _str('ha\u1234\x07ho')) 3371 self.assertRaises(ValueError, setattr, a, "text", 3372 _str('ha\u1234\x02ho')) 3373 3374 self.assertRaises(ValueError, setattr, a, "tail", 3375 _str('ha\u1234\x07ho')) 3376 self.assertRaises(ValueError, setattr, a, "tail", 3377 _str('ha\u1234\x02ho')) 3378 3379 self.assertRaises(ValueError, Element, 3380 _str('ha\u1234\x07ho')) 3381 self.assertRaises(ValueError, Element, 3382 _str('ha\u1234\x02ho'))
3383
3384 - def test_encoding_tostring_utf16(self):
3385 # ElementTree fails to serialize this 3386 tostring = self.etree.tostring 3387 Element = self.etree.Element 3388 SubElement = self.etree.SubElement 3389 3390 a = Element('a') 3391 b = SubElement(a, 'b') 3392 c = SubElement(a, 'c') 3393 3394 result = tostring(a, encoding='UTF-16') 3395 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 3396 canonicalize(result))
3397
3398 - def test_tostring_none(self):
3399 # ElementTree raises an AssertionError here 3400 tostring = self.etree.tostring 3401 self.assertRaises(TypeError, self.etree.tostring, None)
3402
3403 - def test_tostring_pretty(self):
3404 tostring = self.etree.tostring 3405 Element = self.etree.Element 3406 SubElement = self.etree.SubElement 3407 3408 a = Element('a') 3409 b = SubElement(a, 'b') 3410 c = SubElement(a, 'c') 3411 3412 result = tostring(a) 3413 self.assertEqual(result, _bytes("<a><b/><c/></a>")) 3414 3415 result = tostring(a, pretty_print=False) 3416 self.assertEqual(result, _bytes("<a><b/><c/></a>")) 3417 3418 result = tostring(a, pretty_print=True) 3419 self.assertEqual(result, _bytes("<a>\n <b/>\n <c/>\n</a>\n"))
3420
3421 - def test_tostring_with_tail(self):
3422 tostring = self.etree.tostring 3423 Element = self.etree.Element 3424 SubElement = self.etree.SubElement 3425 3426 a = Element('a') 3427 a.tail = "aTAIL" 3428 b = SubElement(a, 'b') 3429 b.tail = "bTAIL" 3430 c = SubElement(a, 'c') 3431 3432 result = tostring(a) 3433 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL")) 3434 3435 result = tostring(a, with_tail=False) 3436 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>")) 3437 3438 result = tostring(a, with_tail=True) 3439 self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
3440
3441 - def test_tostring_method_html_with_tail(self):
3442 tostring = self.etree.tostring 3443 html = self.etree.fromstring( 3444 '<html><body>' 3445 '<div><p>Some text<i>\r\n</i></p></div>\r\n' 3446 '</body></html>', 3447 parser=self.etree.HTMLParser()) 3448 self.assertEqual(html.tag, 'html') 3449 div = html.find('.//div') 3450 self.assertEqual(div.tail, '\r\n') 3451 result = tostring(div, method='html') 3452 self.assertEqual( 3453 result, 3454 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n")) 3455 result = tostring(div, method='html', with_tail=True) 3456 self.assertEqual( 3457 result, 3458 _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n")) 3459 result = tostring(div, method='html', with_tail=False) 3460 self.assertEqual( 3461 result, 3462 _bytes("<div><p>Some text<i>\r\n</i></p></div>"))
3463
3464 - def test_standalone(self):
3465 tostring = self.etree.tostring 3466 XML = self.etree.XML 3467 ElementTree = self.etree.ElementTree 3468 Element = self.etree.Element 3469 3470 tree = Element("root").getroottree() 3471 self.assertEqual(None, tree.docinfo.standalone) 3472 3473 tree = XML(_bytes("<root/>")).getroottree() 3474 self.assertEqual(None, tree.docinfo.standalone) 3475 3476 tree = XML(_bytes( 3477 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>" 3478 )).getroottree() 3479 self.assertEqual(True, tree.docinfo.standalone) 3480 3481 tree = XML(_bytes( 3482 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>" 3483 )).getroottree() 3484 self.assertEqual(False, tree.docinfo.standalone)
3485
3486 - def test_tostring_standalone(self):
3487 tostring = self.etree.tostring 3488 XML = self.etree.XML 3489 ElementTree = self.etree.ElementTree 3490 3491 root = XML(_bytes("<root/>")) 3492 3493 tree = ElementTree(root) 3494 self.assertEqual(None, tree.docinfo.standalone) 3495 3496 result = tostring(root, xml_declaration=True, encoding="ASCII") 3497 self.assertEqual(result, _bytes( 3498 "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 3499 3500 result = tostring(root, xml_declaration=True, encoding="ASCII", 3501 standalone=True) 3502 self.assertEqual(result, _bytes( 3503 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>")) 3504 3505 tree = ElementTree(XML(result)) 3506 self.assertEqual(True, tree.docinfo.standalone) 3507 3508 result = tostring(root, xml_declaration=True, encoding="ASCII", 3509 standalone=False) 3510 self.assertEqual(result, _bytes( 3511 "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>")) 3512 3513 tree = ElementTree(XML(result)) 3514 self.assertEqual(False, tree.docinfo.standalone)
3515
3516 - def test_tostring_standalone_in_out(self):
3517 tostring = self.etree.tostring 3518 XML = self.etree.XML 3519 ElementTree = self.etree.ElementTree 3520 3521 root = XML(_bytes( 3522 "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>")) 3523 3524 tree = ElementTree(root) 3525 self.assertEqual(True, tree.docinfo.standalone) 3526 3527 result = tostring(root, xml_declaration=True, encoding="ASCII") 3528 self.assertEqual(result, _bytes( 3529 "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 3530 3531 result = tostring(root, xml_declaration=True, encoding="ASCII", 3532 standalone=True) 3533 self.assertEqual(result, _bytes( 3534 "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
3535
3536 - def test_tostring_method_text_encoding(self):
3537 tostring = self.etree.tostring 3538 Element = self.etree.Element 3539 SubElement = self.etree.SubElement 3540 3541 a = Element('a') 3542 a.text = "A" 3543 a.tail = "tail" 3544 b = SubElement(a, 'b') 3545 b.text = "B" 3546 b.tail = _str("Søk på nettet") 3547 c = SubElement(a, 'c') 3548 c.text = "C" 3549 3550 result = tostring(a, method="text", encoding="UTF-16") 3551 3552 self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"), 3553 result)
3554
3555 - def test_tostring_method_text_unicode(self):
3556 tostring = self.etree.tostring 3557 Element = self.etree.Element 3558 SubElement = self.etree.SubElement 3559 3560 a = Element('a') 3561 a.text = _str('Søk på nettetA') 3562 a.tail = "tail" 3563 b = SubElement(a, 'b') 3564 b.text = "B" 3565 b.tail = _str('Søk på nettetB') 3566 c = SubElement(a, 'c') 3567 c.text = "C" 3568 3569 self.assertRaises(UnicodeEncodeError, 3570 tostring, a, method="text") 3571 3572 self.assertEqual( 3573 _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'), 3574 tostring(a, encoding="UTF-8", method="text"))
3575
3576 - def test_tounicode(self):
3577 tounicode = self.etree.tounicode 3578 Element = self.etree.Element 3579 SubElement = self.etree.SubElement 3580 3581 a = Element('a') 3582 b = SubElement(a, 'b') 3583 c = SubElement(a, 'c') 3584 3585 self.assertTrue(isinstance(tounicode(a), _unicode)) 3586 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 3587 canonicalize(tounicode(a)))
3588
3589 - def test_tounicode_element(self):
3590 tounicode = self.etree.tounicode 3591 Element = self.etree.Element 3592 SubElement = self.etree.SubElement 3593 3594 a = Element('a') 3595 b = SubElement(a, 'b') 3596 c = SubElement(a, 'c') 3597 d = SubElement(c, 'd') 3598 self.assertTrue(isinstance(tounicode(b), _unicode)) 3599 self.assertTrue(isinstance(tounicode(c), _unicode)) 3600 self.assertEqual(_bytes('<b></b>'), 3601 canonicalize(tounicode(b))) 3602 self.assertEqual(_bytes('<c><d></d></c>'), 3603 canonicalize(tounicode(c)))
3604
3605 - def test_tounicode_none(self):
3606 tounicode = self.etree.tounicode 3607 self.assertRaises(TypeError, self.etree.tounicode, None)
3608
3609 - def test_tounicode_element_tail(self):
3610 tounicode = self.etree.tounicode 3611 Element = self.etree.Element 3612 SubElement = self.etree.SubElement 3613 3614 a = Element('a') 3615 b = SubElement(a, 'b') 3616 c = SubElement(a, 'c') 3617 d = SubElement(c, 'd') 3618 b.tail = 'Foo' 3619 3620 self.assertTrue(isinstance(tounicode(b), _unicode)) 3621 self.assertTrue(tounicode(b) == '<b/>Foo' or 3622 tounicode(b) == '<b />Foo')
3623
3624 - def test_tounicode_pretty(self):
3625 tounicode = self.etree.tounicode 3626 Element = self.etree.Element 3627 SubElement = self.etree.SubElement 3628 3629 a = Element('a') 3630 b = SubElement(a, 'b') 3631 c = SubElement(a, 'c') 3632 3633 result = tounicode(a) 3634 self.assertEqual(result, "<a><b/><c/></a>") 3635 3636 result = tounicode(a, pretty_print=False) 3637 self.assertEqual(result, "<a><b/><c/></a>") 3638 3639 result = tounicode(a, pretty_print=True) 3640 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3641
3642 - def test_tostring_unicode(self):
3643 tostring = self.etree.tostring 3644 Element = self.etree.Element 3645 SubElement = self.etree.SubElement 3646 3647 a = Element('a') 3648 b = SubElement(a, 'b') 3649 c = SubElement(a, 'c') 3650 3651 self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode)) 3652 self.assertEqual(_bytes('<a><b></b><c></c></a>'), 3653 canonicalize(tostring(a, encoding=_unicode)))
3654
3655 - def test_tostring_unicode_element(self):
3656 tostring = self.etree.tostring 3657 Element = self.etree.Element 3658 SubElement = self.etree.SubElement 3659 3660 a = Element('a') 3661 b = SubElement(a, 'b') 3662 c = SubElement(a, 'c') 3663 d = SubElement(c, 'd') 3664 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 3665 self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode)) 3666 self.assertEqual(_bytes('<b></b>'), 3667 canonicalize(tostring(b, encoding=_unicode))) 3668 self.assertEqual(_bytes('<c><d></d></c>'), 3669 canonicalize(tostring(c, encoding=_unicode)))
3670
3671 - def test_tostring_unicode_none(self):
3672 tostring = self.etree.tostring 3673 self.assertRaises(TypeError, self.etree.tostring, 3674 None, encoding=_unicode)
3675
3676 - def test_tostring_unicode_element_tail(self):
3677 tostring = self.etree.tostring 3678 Element = self.etree.Element 3679 SubElement = self.etree.SubElement 3680 3681 a = Element('a') 3682 b = SubElement(a, 'b') 3683 c = SubElement(a, 'c') 3684 d = SubElement(c, 'd') 3685 b.tail = 'Foo' 3686 3687 self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 3688 self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or 3689 tostring(b, encoding=_unicode) == '<b />Foo')
3690
3691 - def test_tostring_unicode_pretty(self):
3692 tostring = self.etree.tostring 3693 Element = self.etree.Element 3694 SubElement = self.etree.SubElement 3695 3696 a = Element('a') 3697 b = SubElement(a, 'b') 3698 c = SubElement(a, 'c') 3699 3700 result = tostring(a, encoding=_unicode) 3701 self.assertEqual(result, "<a><b/><c/></a>") 3702 3703 result = tostring(a, encoding=_unicode, pretty_print=False) 3704 self.assertEqual(result, "<a><b/><c/></a>") 3705 3706 result = tostring(a, encoding=_unicode, pretty_print=True) 3707 self.assertEqual(result, "<a>\n <b/>\n <c/>\n</a>\n")
3708
3709 - def test_pypy_proxy_collect(self):
3710 root = etree.Element('parent') 3711 etree.SubElement(root, 'child') 3712 3713 self.assertEqual(len(root), 1) 3714 self.assertEqual(root[0].tag, 'child') 3715 3716 # in PyPy, GC used to kill the Python proxy instance without cleanup 3717 gc.collect() 3718 self.assertEqual(len(root), 1) 3719 self.assertEqual(root[0].tag, 'child')
3720
3721 - def test_element_refcycle(self):
3722 class SubEl(etree.ElementBase): 3723 pass
3724 3725 el1 = SubEl() 3726 el2 = SubEl() 3727 self.assertEqual('SubEl', el1.tag) 3728 self.assertEqual('SubEl', el2.tag) 3729 el1.other = el2 3730 el2.other = el1 3731 3732 del el1, el2 3733 gc.collect() 3734 # not really testing anything here, but it shouldn't crash 3735
3736 - def test_proxy_collect_siblings(self):
3737 root = etree.Element('parent') 3738 c1 = etree.SubElement(root, 'child1') 3739 c2 = etree.SubElement(root, 'child2') 3740 3741 root.remove(c1) 3742 root.remove(c2) 3743 c1.addnext(c2) 3744 del c1 3745 # trigger deallocation attempt of c1 3746 c2.getprevious() 3747 # make sure it wasn't deallocated 3748 self.assertEqual('child1', c2.getprevious().tag)
3749
3750 - def test_proxy_collect_siblings_text(self):
3751 root = etree.Element('parent') 3752 c1 = etree.SubElement(root, 'child1') 3753 c2 = etree.SubElement(root, 'child2') 3754 3755 root.remove(c1) 3756 root.remove(c2) 3757 c1.addnext(c2) 3758 c1.tail = 'abc' 3759 c2.tail = 'xyz' 3760 del c1 3761 # trigger deallocation attempt of c1 3762 c2.getprevious() 3763 # make sure it wasn't deallocated 3764 self.assertEqual('child1', c2.getprevious().tag) 3765 self.assertEqual('abc', c2.getprevious().tail)
3766 3767 # helper methods 3768
3769 - def _writeElement(self, element, encoding='us-ascii', compression=0):
3770 """Write out element for comparison. 3771 """ 3772 ElementTree = self.etree.ElementTree 3773 f = BytesIO() 3774 tree = ElementTree(element=element) 3775 tree.write(f, encoding=encoding, compression=compression) 3776 data = f.getvalue() 3777 if compression: 3778 data = zlib.decompress(data) 3779 return canonicalize(data)
3780 3781
3782 -class _XIncludeTestCase(HelperTestCase):
3783 - def test_xinclude_text(self):
3784 filename = fileInTestDir('test_broken.xml') 3785 root = etree.XML(_bytes('''\ 3786 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 3787 <xi:include href="%s" parse="text"/> 3788 </doc> 3789 ''' % path2url(filename))) 3790 old_text = root.text 3791 content = read_file(filename) 3792 old_tail = root[0].tail 3793 3794 self.include( etree.ElementTree(root) ) 3795 self.assertEqual(old_text + content + old_tail, 3796 root.text)
3797
3798 - def test_xinclude(self):
3799 tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 3800 self.assertNotEqual( 3801 'a', 3802 tree.getroot()[1].tag) 3803 # process xincludes 3804 self.include( tree ) 3805 # check whether we find it replaced with included data 3806 self.assertEqual( 3807 'a', 3808 tree.getroot()[1].tag)
3809
3810 - def test_xinclude_resolver(self):
3811 class res(etree.Resolver): 3812 include_text = read_file(fileInTestDir('test.xml')) 3813 called = {} 3814 def resolve(self, url, id, context): 3815 if url.endswith(".dtd"): 3816 self.called["dtd"] = True 3817 return self.resolve_filename( 3818 fileInTestDir('test.dtd'), context) 3819 elif url.endswith("test_xinclude.xml"): 3820 self.called["input"] = True 3821 return None # delegate to default resolver 3822 else: 3823 self.called["include"] = True 3824 return self.resolve_string(self.include_text, context)
3825 3826 res_instance = res() 3827 parser = etree.XMLParser(load_dtd = True) 3828 parser.resolvers.add(res_instance) 3829 3830 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 3831 parser = parser) 3832 3833 self.include(tree) 3834 3835 called = list(res_instance.called.items()) 3836 called.sort() 3837 self.assertEqual( 3838 [("dtd", True), ("include", True), ("input", True)], 3839 called) 3840
3841 - def test_xinclude_resolver_recursive(self):
3842 data = textwrap.dedent(''' 3843 <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 3844 <foo/> 3845 <xi:include href="./test.xml" /> 3846 </doc> 3847 ''') 3848 3849 class Resolver(etree.Resolver): 3850 called = {} 3851 3852 def resolve(self, url, id, context): 3853 if url.endswith("test_xinclude.xml"): 3854 assert not self.called.get("input") 3855 self.called["input"] = True 3856 return None # delegate to default resolver 3857 elif url.endswith('/test5.xml'): 3858 assert not self.called.get("DONE") 3859 self.called["DONE"] = True 3860 return self.resolve_string('<DONE/>', context) 3861 else: 3862 _, filename = url.rsplit('/', 1) 3863 assert not self.called.get(filename) 3864 self.called[filename] = True 3865 next_data = data.replace( 3866 'test.xml', 'test%d.xml' % len(self.called)) 3867 return self.resolve_string(next_data, context)
3868 3869 res_instance = Resolver() 3870 parser = etree.XMLParser(load_dtd=True) 3871 parser.resolvers.add(res_instance) 3872 3873 tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 3874 parser=parser) 3875 3876 self.include(tree) 3877 3878 called = list(res_instance.called.items()) 3879 called.sort() 3880 self.assertEqual( 3881 [("DONE", True), ("input", True), ("test.xml", True), 3882 ("test2.xml", True), ("test3.xml", True), ("test4.xml", True)], 3883 called) 3884 3885
3886 -class ETreeXIncludeTestCase(_XIncludeTestCase):
3887 - def include(self, tree):
3888 tree.xinclude()
3889 3890
3891 -class ElementIncludeTestCase(_XIncludeTestCase):
3892 from lxml import ElementInclude
3893 - def include(self, tree):
3894 self.ElementInclude.include(tree.getroot())
3895 3896
3897 -class ETreeC14NTestCase(HelperTestCase):
3898 - def test_c14n(self):
3899 tree = self.parse(_bytes('<a><b/></a>')) 3900 f = BytesIO() 3901 tree.write_c14n(f) 3902 s = f.getvalue() 3903 self.assertEqual(_bytes('<a><b></b></a>'), 3904 s)
3905
3906 - def test_c14n_gzip(self):
3907 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3908 f = BytesIO() 3909 tree.write_c14n(f, compression=9) 3910 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue())) 3911 try: 3912 s = gzfile.read() 3913 finally: 3914 gzfile.close() 3915 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 3916 s)
3917
3918 - def test_c14n_file(self):
3919 tree = self.parse(_bytes('<a><b/></a>')) 3920 handle, filename = tempfile.mkstemp() 3921 try: 3922 tree.write_c14n(filename) 3923 data = read_file(filename, 'rb') 3924 finally: 3925 os.close(handle) 3926 os.remove(filename) 3927 self.assertEqual(_bytes('<a><b></b></a>'), 3928 data)
3929
3930 - def test_c14n_file_gzip(self):
3931 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 3932 handle, filename = tempfile.mkstemp() 3933 try: 3934 tree.write_c14n(filename, compression=9) 3935 f = gzip.open(filename, 'rb') 3936 try: 3937 data = f.read() 3938 finally: 3939 f.close() 3940 finally: 3941 os.close(handle) 3942 os.remove(filename) 3943 self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 3944 data)
3945
3946 - def test_c14n_with_comments(self):
3947 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 3948 f = BytesIO() 3949 tree.write_c14n(f) 3950 s = f.getvalue() 3951 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3952 s) 3953 f = BytesIO() 3954 tree.write_c14n(f, with_comments=True) 3955 s = f.getvalue() 3956 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3957 s) 3958 f = BytesIO() 3959 tree.write_c14n(f, with_comments=False) 3960 s = f.getvalue() 3961 self.assertEqual(_bytes('<a><b></b></a>'), 3962 s)
3963
3965 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 3966 s = etree.tostring(tree, method='c14n') 3967 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3968 s) 3969 s = etree.tostring(tree, method='c14n', with_comments=True) 3970 self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 3971 s) 3972 s = etree.tostring(tree, method='c14n', with_comments=False) 3973 self.assertEqual(_bytes('<a><b></b></a>'), 3974 s)
3975
3977 tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 3978 s = etree.tostring(tree.getroot(), method='c14n') 3979 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 3980 s) 3981 s = etree.tostring(tree.getroot(), method='c14n', with_comments=True) 3982 self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 3983 s) 3984 s = etree.tostring(tree.getroot(), method='c14n', with_comments=False) 3985 self.assertEqual(_bytes('<a><b></b></a>'), 3986 s)
3987
3988 - def test_c14n_exclusive(self):
3989 tree = self.parse(_bytes( 3990 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 3991 f = BytesIO() 3992 tree.write_c14n(f) 3993 s = f.getvalue() 3994 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 3995 s) 3996 f = BytesIO() 3997 tree.write_c14n(f, exclusive=False) 3998 s = f.getvalue() 3999 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4000 s) 4001 f = BytesIO() 4002 tree.write_c14n(f, exclusive=True) 4003 s = f.getvalue() 4004 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 4005 s) 4006 4007 f = BytesIO() 4008 tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z']) 4009 s = f.getvalue() 4010 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'), 4011 s)
4012
4014 tree = self.parse(_bytes( 4015 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 4016 s = etree.tostring(tree, method='c14n') 4017 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4018 s) 4019 s = etree.tostring(tree, method='c14n', exclusive=False) 4020 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4021 s) 4022 s = etree.tostring(tree, method='c14n', exclusive=True) 4023 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 4024 s) 4025 4026 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 4027 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'), 4028 s)
4029
4031 tree = self.parse(_bytes( 4032 '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 4033 s = etree.tostring(tree.getroot(), method='c14n') 4034 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4035 s) 4036 s = etree.tostring(tree.getroot(), method='c14n', exclusive=False) 4037 self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4038 s) 4039 s = etree.tostring(tree.getroot(), method='c14n', exclusive=True) 4040 self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 4041 s) 4042 4043 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False) 4044 self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 4045 s) 4046 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True) 4047 self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'), 4048 s) 4049 4050 s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 4051 self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 4052 s)
4053
4055 """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)""" 4056 tree = self.parse(_bytes( 4057 '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 4058 4059 s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z']) 4060 self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 4061 s)
4062 4063
4064 -class ETreeWriteTestCase(HelperTestCase):
4065 - def test_write(self):
4066 tree = self.parse(_bytes('<a><b/></a>')) 4067 f = BytesIO() 4068 tree.write(f) 4069 s = f.getvalue() 4070 self.assertEqual(_bytes('<a><b/></a>'), 4071 s)
4072
4073 - def test_write_gzip(self):
4074 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4075 f = BytesIO() 4076 tree.write(f, compression=9) 4077 gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue())) 4078 try: 4079 s = gzfile.read() 4080 finally: 4081 gzfile.close() 4082 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4083 s)
4084
4085 - def test_write_gzip_level(self):
4086 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4087 f = BytesIO() 4088 tree.write(f, compression=0) 4089 s0 = f.getvalue() 4090 4091 f = BytesIO() 4092 tree.write(f) 4093 self.assertEqual(f.getvalue(), s0) 4094 4095 f = BytesIO() 4096 tree.write(f, compression=1) 4097 s = f.getvalue() 4098 self.assertTrue(len(s) <= len(s0)) 4099 gzfile = gzip.GzipFile(fileobj=BytesIO(s)) 4100 try: 4101 s1 = gzfile.read() 4102 finally: 4103 gzfile.close() 4104 4105 f = BytesIO() 4106 tree.write(f, compression=9) 4107 s = f.getvalue() 4108 self.assertTrue(len(s) <= len(s0)) 4109 gzfile = gzip.GzipFile(fileobj=BytesIO(s)) 4110 try: 4111 s9 = gzfile.read() 4112 finally: 4113 gzfile.close() 4114 4115 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4116 s0) 4117 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4118 s1) 4119 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4120 s9)
4121
4122 - def test_write_file(self):
4123 tree = self.parse(_bytes('<a><b/></a>')) 4124 handle, filename = tempfile.mkstemp() 4125 try: 4126 tree.write(filename) 4127 data = read_file(filename, 'rb') 4128 finally: 4129 os.close(handle) 4130 os.remove(filename) 4131 self.assertEqual(_bytes('<a><b/></a>'), 4132 data)
4133
4134 - def test_write_file_gzip(self):
4135 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4136 handle, filename = tempfile.mkstemp() 4137 try: 4138 tree.write(filename, compression=9) 4139 f = gzip.open(filename, 'rb') 4140 try: 4141 data = f.read() 4142 finally: 4143 f.close() 4144 finally: 4145 os.close(handle) 4146 os.remove(filename) 4147 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4148 data)
4149
4150 - def test_write_file_gzip_parse(self):
4151 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4152 handle, filename = tempfile.mkstemp() 4153 try: 4154 tree.write(filename, compression=9) 4155 data = etree.tostring(etree.parse(filename)) 4156 finally: 4157 os.close(handle) 4158 os.remove(filename) 4159 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4160 data)
4161
4163 tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 4164 handle, filename = tempfile.mkstemp() 4165 try: 4166 tree.write(filename, compression=9) 4167 data = etree.tostring(etree.parse( 4168 gzip.GzipFile(filename))) 4169 finally: 4170 os.close(handle) 4171 os.remove(filename) 4172 self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 4173 data)
4174
4175 -class ETreeErrorLogTest(HelperTestCase):
4176 etree = etree 4177
4178 - def test_parse_error_logging(self):
4179 parse = self.etree.parse 4180 f = BytesIO('<a><b></c></b></a>') 4181 self.etree.clear_error_log() 4182 try: 4183 parse(f) 4184 logs = None 4185 except SyntaxError: 4186 e = sys.exc_info()[1] 4187 logs = e.error_log 4188 f.close() 4189 self.assertTrue([ log for log in logs 4190 if 'mismatch' in log.message ]) 4191 self.assertTrue([ log for log in logs 4192 if 'PARSER' in log.domain_name]) 4193 self.assertTrue([ log for log in logs 4194 if 'ERR_TAG_NAME_MISMATCH' in log.type_name ]) 4195 self.assertTrue([ log for log in logs 4196 if 1 == log.line ]) 4197 self.assertTrue([ log for log in logs 4198 if 15 == log.column ])
4199
4200 - def _test_python_error_logging(self):
4201 """This can't really be tested as long as there isn't a way to 4202 reset the logging setup ... 4203 """ 4204 parse = self.etree.parse 4205 4206 messages = [] 4207 class Logger(self.etree.PyErrorLog): 4208 def log(self, entry, message, *args): 4209 messages.append(message)
4210 4211 self.etree.use_global_python_log(Logger()) 4212 f = BytesIO('<a><b></c></b></a>') 4213 try: 4214 parse(f) 4215 except SyntaxError: 4216 pass 4217 f.close() 4218 4219 self.assertTrue([ message for message in messages 4220 if 'mismatch' in message ]) 4221 self.assertTrue([ message for message in messages 4222 if ':PARSER:' in message]) 4223 self.assertTrue([ message for message in messages 4224 if ':ERR_TAG_NAME_MISMATCH:' in message ]) 4225 self.assertTrue([ message for message in messages 4226 if ':1:15:' in message ]) 4227 4228
4229 -class XMLPullParserTest(unittest.TestCase):
4230 etree = etree 4231
4232 - def assert_event_tags(self, events, expected):
4233 self.assertEqual([(action, elem.tag) for action, elem in events], 4234 expected)
4235
4237 class Target(object): 4238 def start(self, tag, attrib): 4239 return 'start(%s)' % tag
4240 def end(self, tag): 4241 return 'end(%s)' % tag
4242 def close(self): 4243 return 'close()' 4244 4245 parser = self.etree.XMLPullParser(target=Target()) 4246 events = parser.read_events() 4247 4248 parser.feed('<root><element>') 4249 self.assertFalse(list(events)) 4250 self.assertFalse(list(events)) 4251 parser.feed('</element><child>') 4252 self.assertEqual([('end', 'end(element)')], list(events)) 4253 parser.feed('</child>') 4254 self.assertEqual([('end', 'end(child)')], list(events)) 4255 parser.feed('</root>') 4256 self.assertEqual([('end', 'end(root)')], list(events)) 4257 self.assertFalse(list(events)) 4258 self.assertEqual('close()', parser.close()) 4259
4260 - def test_pull_from_simple_target_start_end(self):
4261 class Target(object): 4262 def start(self, tag, attrib): 4263 return 'start(%s)' % tag
4264 def end(self, tag): 4265 return 'end(%s)' % tag 4266 def close(self): 4267 return 'close()' 4268 4269 parser = self.etree.XMLPullParser( 4270 ['start', 'end'], target=Target()) 4271 events = parser.read_events() 4272 4273 parser.feed('<root><element>') 4274 self.assertEqual( 4275 [('start', 'start(root)'), ('start', 'start(element)')], 4276 list(events)) 4277 self.assertFalse(list(events)) 4278 parser.feed('</element><child>') 4279 self.assertEqual( 4280 [('end', 'end(element)'), ('start', 'start(child)')], 4281 list(events)) 4282 parser.feed('</child>') 4283 self.assertEqual( 4284 [('end', 'end(child)')], 4285 list(events)) 4286 parser.feed('</root>') 4287 self.assertEqual( 4288 [('end', 'end(root)')], 4289 list(events)) 4290 self.assertFalse(list(events)) 4291 self.assertEqual('close()', parser.close()) 4292
4293 - def test_pull_from_tree_builder(self):
4294 parser = self.etree.XMLPullParser( 4295 ['start', 'end'], target=etree.TreeBuilder()) 4296 events = parser.read_events() 4297 4298 parser.feed('<root><element>') 4299 self.assert_event_tags( 4300 events, [('start', 'root'), ('start', 'element')]) 4301 self.assertFalse(list(events)) 4302 parser.feed('</element><child>') 4303 self.assert_event_tags( 4304 events, [('end', 'element'), ('start', 'child')]) 4305 parser.feed('</child>') 4306 self.assert_event_tags( 4307 events, [('end', 'child')]) 4308 parser.feed('</root>') 4309 self.assert_event_tags( 4310 events, [('end', 'root')]) 4311 self.assertFalse(list(events)) 4312 root = parser.close() 4313 self.assertEqual('root', root.tag)
4314
4315 - def test_pull_from_tree_builder_subclass(self):
4316 class Target(etree.TreeBuilder): 4317 def end(self, tag): 4318 el = super(Target, self).end(tag) 4319 el.tag += '-huhu' 4320 return el
4321 4322 parser = self.etree.XMLPullParser( 4323 ['start', 'end'], target=Target()) 4324 events = parser.read_events() 4325 4326 parser.feed('<root><element>') 4327 self.assert_event_tags( 4328 events, [('start', 'root'), ('start', 'element')]) 4329 self.assertFalse(list(events)) 4330 parser.feed('</element><child>') 4331 self.assert_event_tags( 4332 events, [('end', 'element-huhu'), ('start', 'child')]) 4333 parser.feed('</child>') 4334 self.assert_event_tags( 4335 events, [('end', 'child-huhu')]) 4336 parser.feed('</root>') 4337 self.assert_event_tags( 4338 events, [('end', 'root-huhu')]) 4339 self.assertFalse(list(events)) 4340 root = parser.close() 4341 self.assertEqual('root-huhu', root.tag) 4342 4343
4344 -def test_suite():
4345 suite = unittest.TestSuite() 4346 suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 4347 suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 4348 suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 4349 suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 4350 suite.addTests([unittest.makeSuite(ETreeWriteTestCase)]) 4351 suite.addTests([unittest.makeSuite(ETreeErrorLogTest)]) 4352 suite.addTests([unittest.makeSuite(XMLPullParserTest)]) 4353 suite.addTests(doctest.DocTestSuite(etree)) 4354 suite.addTests( 4355 [make_doctest('../../../doc/tutorial.txt')]) 4356 if sys.version_info >= (2,6): 4357 # now requires the 'with' statement 4358 suite.addTests( 4359 [make_doctest('../../../doc/api.txt')]) 4360 suite.addTests( 4361 [make_doctest('../../../doc/FAQ.txt')]) 4362 suite.addTests( 4363 [make_doctest('../../../doc/parsing.txt')]) 4364 suite.addTests( 4365 [make_doctest('../../../doc/resolvers.txt')]) 4366 return suite
4367 4368 if __name__ == '__main__': 4369 print('to test use test.py %s' % __file__) 4370