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