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