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