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