| Home | Trees | Indices | Help | 
 | 
|---|
|  | 
   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  from __future__ import absolute_import 
  11   
  12  import os.path 
  13  import unittest 
  14  import copy 
  15  import sys 
  16  import re 
  17  import gc 
  18  import operator 
  19  import tempfile 
  20  import textwrap 
  21  import zlib 
  22  import gzip 
  23  from contextlib import closing, contextmanager 
  24   
  25  from .common_imports import etree, StringIO, BytesIO, HelperTestCase 
  26  from .common_imports import fileInTestDir, fileUrlInTestDir, read_file, path2url 
  27  from .common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest 
  28  from .common_imports import canonicalize, _str, _bytes 
  29   
  30  print("") 
  31  print("TESTED VERSION: %s" % etree.__version__) 
  32  print("    Python:           " + repr(sys.version_info)) 
  33  print("    lxml.etree:       " + repr(etree.LXML_VERSION)) 
  34  print("    libxml used:      " + repr(etree.LIBXML_VERSION)) 
  35  print("    libxml compiled:  " + repr(etree.LIBXML_COMPILED_VERSION)) 
  36  print("    libxslt used:     " + repr(etree.LIBXSLT_VERSION)) 
  37  print("    libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION)) 
  38  print("") 
  39   
  40  try: 
  41      _unicode = unicode 
  42  except NameError: 
  43      # Python 3 
  44      _unicode = str 
  49      handle, filename = tempfile.mkstemp() 
  50      try: 
  51          yield filename 
  52      finally: 
  53          os.close(handle) 
  54          os.remove(filename) 
  55   
  58      """Tests only for etree, not ElementTree""" 
  59      etree = etree 
  60   
  62          self.assertTrue(isinstance(etree.__version__, _unicode)) 
  63          self.assertTrue(isinstance(etree.LXML_VERSION, tuple)) 
  64          self.assertEqual(len(etree.LXML_VERSION), 4) 
  65          self.assertTrue(isinstance(etree.LXML_VERSION[0], int)) 
  66          self.assertTrue(isinstance(etree.LXML_VERSION[1], int)) 
  67          self.assertTrue(isinstance(etree.LXML_VERSION[2], int)) 
  68          self.assertTrue(isinstance(etree.LXML_VERSION[3], int)) 
  69          self.assertTrue(etree.__version__.startswith( 
  70              str(etree.LXML_VERSION[0]))) 
  71   
  73          if hasattr(self.etree, '__pyx_capi__'): 
  74              # newer Pyrex compatible C-API 
  75              self.assertTrue(isinstance(self.etree.__pyx_capi__, dict)) 
  76              self.assertTrue(len(self.etree.__pyx_capi__) > 0) 
  77          else: 
  78              # older C-API mechanism 
  79              self.assertTrue(hasattr(self.etree, '_import_c_api')) 
  80   
  82          import lxml 
  83          includes = lxml.get_include() 
  84          self.assertTrue(includes) 
  85          self.assertTrue(len(includes) >= 2) 
  86          self.assertTrue(os.path.join(os.path.dirname(lxml.__file__), 'includes') in includes, 
  87                          includes) 
  88   
  90          Element = self.etree.Element 
  91          el = Element('name') 
  92          self.assertEqual(el.tag, 'name') 
  93          el = Element('{}name') 
  94          self.assertEqual(el.tag, 'name') 
  95   
  97          Element = self.etree.Element 
  98          el = Element('name') 
  99          self.assertRaises(ValueError, Element, '{}') 
 100          self.assertRaises(ValueError, setattr, el, 'tag', '{}') 
 101   
 102          self.assertRaises(ValueError, Element, '{test}') 
 103          self.assertRaises(ValueError, setattr, el, 'tag', '{test}') 
 104   
 106          Element = self.etree.Element 
 107          self.assertRaises(ValueError, Element, 'p:name') 
 108          self.assertRaises(ValueError, Element, '{test}p:name') 
 109   
 110          el = Element('name') 
 111          self.assertRaises(ValueError, setattr, el, 'tag', 'p:name') 
 112   
 114          Element = self.etree.Element 
 115          self.assertRaises(ValueError, Element, "p'name") 
 116          self.assertRaises(ValueError, Element, 'p"name') 
 117   
 118          self.assertRaises(ValueError, Element, "{test}p'name") 
 119          self.assertRaises(ValueError, Element, '{test}p"name') 
 120   
 121          el = Element('name') 
 122          self.assertRaises(ValueError, setattr, el, 'tag', "p'name") 
 123          self.assertRaises(ValueError, setattr, el, 'tag', 'p"name') 
 124   
 126          Element = self.etree.Element 
 127          self.assertRaises(ValueError, Element, ' name ') 
 128          self.assertRaises(ValueError, Element, 'na me') 
 129          self.assertRaises(ValueError, Element, '{test} name') 
 130   
 131          el = Element('name') 
 132          self.assertRaises(ValueError, setattr, el, 'tag', ' name ') 
 133   
 135          Element = self.etree.Element 
 136          SubElement = self.etree.SubElement 
 137   
 138          el = Element('name') 
 139          self.assertRaises(ValueError, SubElement, el, '{}') 
 140          self.assertRaises(ValueError, SubElement, el, '{test}') 
 141   
 143          Element = self.etree.Element 
 144          SubElement = self.etree.SubElement 
 145   
 146          el = Element('name') 
 147          self.assertRaises(ValueError, SubElement, el, 'p:name') 
 148          self.assertRaises(ValueError, SubElement, el, '{test}p:name') 
 149   
 151          Element = self.etree.Element 
 152          SubElement = self.etree.SubElement 
 153   
 154          el = Element('name') 
 155          self.assertRaises(ValueError, SubElement, el, "p'name") 
 156          self.assertRaises(ValueError, SubElement, el, "{test}p'name") 
 157   
 158          self.assertRaises(ValueError, SubElement, el, 'p"name') 
 159          self.assertRaises(ValueError, SubElement, el, '{test}p"name') 
 160   
 162          Element = self.etree.Element 
 163          SubElement = self.etree.SubElement 
 164   
 165          el = Element('name') 
 166          self.assertRaises(ValueError, SubElement, el, ' name ') 
 167          self.assertRaises(ValueError, SubElement, el, 'na me') 
 168          self.assertRaises(ValueError, SubElement, el, '{test} name') 
 169   
 171          Element = self.etree.Element 
 172          SubElement = self.etree.SubElement 
 173   
 174          el = Element('name') 
 175          self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'}) 
 176          self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'}) 
 177          self.assertEqual(0, len(el)) 
 178   
 180          QName = self.etree.QName 
 181          self.assertRaises(ValueError, QName, '') 
 182          self.assertRaises(ValueError, QName, 'test', '') 
 183   
 185          QName = self.etree.QName 
 186          self.assertRaises(ValueError, QName, 'p:name') 
 187          self.assertRaises(ValueError, QName, 'test', 'p:name') 
 188   
 190          QName = self.etree.QName 
 191          self.assertRaises(ValueError, QName, ' name ') 
 192          self.assertRaises(ValueError, QName, 'na me') 
 193          self.assertRaises(ValueError, QName, 'test', ' name') 
 194   
 196          # ET doesn't have namespace/localname properties on QNames 
 197          QName = self.etree.QName 
 198          namespace, localname = 'http://myns', 'a' 
 199          qname = QName(namespace, localname) 
 200          self.assertEqual(namespace, qname.namespace) 
 201          self.assertEqual(localname, qname.localname) 
 202   
 204          # ET doesn't have namespace/localname properties on QNames 
 205          QName = self.etree.QName 
 206          qname1 = QName('http://myns', 'a') 
 207          a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'}) 
 208   
 209          qname2 = QName(a) 
 210          self.assertEqual(a.tag, qname1.text) 
 211          self.assertEqual(qname1.text, qname2.text) 
 212          self.assertEqual(qname1, qname2) 
 213   
 215          # ET doesn't resove QNames as text values 
 216          etree = self.etree 
 217          qname = etree.QName('http://myns', 'a') 
 218          a = etree.Element(qname, nsmap={'p' : 'http://myns'}) 
 219          a.text = qname 
 220   
 221          self.assertEqual("p:a", a.text) 
 222   
 224          etree = self.etree 
 225          self.assertRaises(ValueError, 
 226                            etree.Element, "root", nsmap={'"' : 'testns'}) 
 227          self.assertRaises(ValueError, 
 228                            etree.Element, "root", nsmap={'&' : 'testns'}) 
 229          self.assertRaises(ValueError, 
 230                            etree.Element, "root", nsmap={'a:b' : 'testns'}) 
 231   
 233          # ET in Py 3.x has no "attrib.has_key()" method 
 234          XML = self.etree.XML 
 235   
 236          root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />')) 
 237          self.assertEqual( 
 238              True, root.attrib.has_key('bar')) 
 239          self.assertEqual( 
 240              False, root.attrib.has_key('baz')) 
 241          self.assertEqual( 
 242              False, root.attrib.has_key('hah')) 
 243          self.assertEqual( 
 244              True, 
 245              root.attrib.has_key('{http://ns.codespeak.net/test}baz')) 
 246   
 248          Element = self.etree.Element 
 249          root = Element("root") 
 250          root.set("attr", "TEST") 
 251          self.assertEqual("TEST", root.get("attr")) 
 252   
 254          # ElementTree accepts arbitrary attribute values 
 255          # lxml.etree allows only strings 
 256          Element = self.etree.Element 
 257   
 258          root = Element("root") 
 259          root.set("attr", "TEST") 
 260          self.assertEqual("TEST", root.get("attr")) 
 261          self.assertRaises(TypeError, root.set, "newattr", 5) 
 262   
 264          Element = self.etree.Element 
 265   
 266          root = Element("root") 
 267          root.set("attr", "TEST") 
 268          self.assertEqual("TEST", root.attrib["attr"]) 
 269   
 270          root2 = Element("root2", root.attrib, attr2='TOAST') 
 271          self.assertEqual("TEST", root2.attrib["attr"]) 
 272          self.assertEqual("TOAST", root2.attrib["attr2"]) 
 273          self.assertEqual(None, root.attrib.get("attr2")) 
 274   
 276          Element = self.etree.Element 
 277   
 278          keys = ["attr%d" % i for i in range(10)] 
 279          values = ["TEST-%d" % i for i in range(10)] 
 280          items = list(zip(keys, values)) 
 281   
 282          root = Element("root") 
 283          for key, value in items: 
 284              root.set(key, value) 
 285          self.assertEqual(keys, root.attrib.keys()) 
 286          self.assertEqual(values, root.attrib.values()) 
 287   
 288          root2 = Element("root2", root.attrib, 
 289                          attr_99='TOAST-1', attr_98='TOAST-2') 
 290          self.assertEqual(['attr_98', 'attr_99'] + keys, 
 291                           root2.attrib.keys()) 
 292          self.assertEqual(['TOAST-2', 'TOAST-1'] + values, 
 293                           root2.attrib.values()) 
 294   
 295          self.assertEqual(keys, root.attrib.keys()) 
 296          self.assertEqual(values, root.attrib.values()) 
 297   
 299          # ElementTree accepts arbitrary attribute values 
 300          # lxml.etree allows only strings, or None for (html5) boolean attributes 
 301          Element = self.etree.Element 
 302          root = Element("root") 
 303          self.assertRaises(TypeError, root.set, "newattr", 5) 
 304          self.assertRaises(TypeError, root.set, "newattr", object) 
 305          self.assertRaises(TypeError, root.set, "newattr", None) 
 306          self.assertRaises(TypeError, root.set, "newattr") 
 307   
 309          XML = self.etree.XML 
 310          xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>') 
 311   
 312          root = XML(xml) 
 313          self.etree.strip_attributes(root, 'a') 
 314          self.assertEqual(_bytes('<test b="10" c="20"><x b="2"></x></test>'), 
 315                            self._writeElement(root)) 
 316   
 317          root = XML(xml) 
 318          self.etree.strip_attributes(root, 'b', 'c') 
 319          self.assertEqual(_bytes('<test a="5"><x a="4"></x></test>'), 
 320                            self._writeElement(root)) 
 321   
 323          XML = self.etree.XML 
 324          xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>') 
 325   
 326          root = XML(xml) 
 327          self.etree.strip_attributes(root, 'a') 
 328          self.assertEqual( 
 329              _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'), 
 330              self._writeElement(root)) 
 331   
 332          root = XML(xml) 
 333          self.etree.strip_attributes(root, '{http://test/ns}a', 'c') 
 334          self.assertEqual( 
 335              _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'), 
 336              self._writeElement(root)) 
 337   
 338          root = XML(xml) 
 339          self.etree.strip_attributes(root, '{http://test/ns}*') 
 340          self.assertEqual( 
 341              _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'), 
 342              self._writeElement(root)) 
 343   
 345          XML = self.etree.XML 
 346          xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>') 
 347   
 348          root = XML(xml) 
 349          self.etree.strip_elements(root, 'a') 
 350          self.assertEqual(_bytes('<test><x></x></test>'), 
 351                            self._writeElement(root)) 
 352   
 353          root = XML(xml) 
 354          self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z') 
 355          self.assertEqual(_bytes('<test><a></a><x><a></a></x></test>'), 
 356                            self._writeElement(root)) 
 357   
 358          root = XML(xml) 
 359          self.etree.strip_elements(root, 'c') 
 360          self.assertEqual(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'), 
 361                            self._writeElement(root)) 
 362   
 364          XML = self.etree.XML 
 365          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>') 
 366   
 367          root = XML(xml) 
 368          self.etree.strip_elements(root, 'a') 
 369          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>'), 
 370                            self._writeElement(root)) 
 371   
 372          root = XML(xml) 
 373          self.etree.strip_elements(root, '{urn:a}b', 'c') 
 374          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>'), 
 375                            self._writeElement(root)) 
 376   
 377          root = XML(xml) 
 378          self.etree.strip_elements(root, '{urn:a}*', 'c') 
 379          self.assertEqual(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 
 380                            self._writeElement(root)) 
 381   
 382          root = XML(xml) 
 383          self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False) 
 384          self.assertEqual(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'), 
 385                            self._writeElement(root)) 
 386   
 405   
 431   
 458   
 485   
 504   
 517   
 519          # lxml.etree separates target and text 
 520          Element = self.etree.Element 
 521          SubElement = self.etree.SubElement 
 522          ProcessingInstruction = self.etree.ProcessingInstruction 
 523   
 524          a = Element('a') 
 525          a.append(ProcessingInstruction('foo', 'some more text')) 
 526          self.assertEqual(a[0].target, 'foo') 
 527          self.assertEqual(a[0].text, 'some more text') 
 528   
 530          XML = self.etree.XML 
 531          root = XML(_bytes("<test><?mypi my test ?></test>")) 
 532          self.assertEqual(root[0].target, "mypi") 
 533          self.assertEqual(root[0].text, "my test ") 
 534   
 536          XML = self.etree.XML 
 537          root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>")) 
 538          self.assertEqual(root[0].target, "mypi") 
 539          self.assertEqual(root[0].get('my'), "1") 
 540          self.assertEqual(root[0].get('test'), " abc ") 
 541          self.assertEqual(root[0].get('quotes'), "' '") 
 542          self.assertEqual(root[0].get('only'), None) 
 543          self.assertEqual(root[0].get('names'), None) 
 544          self.assertEqual(root[0].get('nope'), None) 
 545   
 547          XML = self.etree.XML 
 548          root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>")) 
 549          self.assertEqual(root[0].target, "mypi") 
 550          self.assertEqual(root[0].attrib['my'], "1") 
 551          self.assertEqual(root[0].attrib['test'], " abc ") 
 552          self.assertEqual(root[0].attrib['quotes'], "' '") 
 553          self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only') 
 554          self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names') 
 555          self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope') 
 556   
 558          # previously caused a crash 
 559          ProcessingInstruction = self.etree.ProcessingInstruction 
 560           
 561          a = ProcessingInstruction("PI", "ONE") 
 562          b = copy.deepcopy(a) 
 563          b.text = "ANOTHER" 
 564   
 565          self.assertEqual('ONE',     a.text) 
 566          self.assertEqual('ANOTHER', b.text) 
 567   
 569          XML = self.etree.XML 
 570          tostring = self.etree.tostring 
 571          root = XML(_bytes("<?mypi my test ?><test/><!--comment -->")) 
 572          tree1 = self.etree.ElementTree(root) 
 573          self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"), 
 574                            tostring(tree1)) 
 575   
 576          tree2 = copy.deepcopy(tree1) 
 577          self.assertEqual(_bytes("<?mypi my test ?><test/><!--comment -->"), 
 578                            tostring(tree2)) 
 579   
 580          root2 = copy.deepcopy(tree1.getroot()) 
 581          self.assertEqual(_bytes("<test/>"), 
 582                            tostring(root2)) 
 583   
 585          XML = self.etree.XML 
 586          tostring = self.etree.tostring 
 587          xml = _bytes('<!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>') 
 588          root = XML(xml) 
 589          tree1 = self.etree.ElementTree(root) 
 590          self.assertEqual(xml, tostring(tree1)) 
 591   
 592          tree2 = copy.deepcopy(tree1) 
 593          self.assertEqual(xml, tostring(tree2)) 
 594   
 595          root2 = copy.deepcopy(tree1.getroot()) 
 596          self.assertEqual(_bytes("<test/>"), 
 597                            tostring(root2)) 
 598   
 600          XML = self.etree.XML 
 601          tostring = self.etree.tostring 
 602          xml = _bytes('<!-- comment --><!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>') 
 603          root = XML(xml) 
 604          tree1 = self.etree.ElementTree(root) 
 605          self.assertEqual(xml, tostring(tree1)) 
 606   
 607          tree2 = copy.deepcopy(tree1) 
 608          self.assertEqual(xml, tostring(tree2)) 
 609   
 611          fromstring = self.etree.fromstring 
 612          tostring = self.etree.tostring 
 613          XMLParser = self.etree.XMLParser 
 614   
 615          xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 
 616          parser = XMLParser(remove_comments=True) 
 617          root = fromstring(xml, parser) 
 618          self.assertEqual( 
 619              _bytes('<a><b><c/></b></a>'), 
 620              tostring(root)) 
 621   
 623          parse = self.etree.parse 
 624          tostring = self.etree.tostring 
 625          XMLParser = self.etree.XMLParser 
 626   
 627          xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>') 
 628   
 629          f = BytesIO(xml) 
 630          tree = parse(f) 
 631          self.assertEqual( 
 632              xml, 
 633              tostring(tree)) 
 634   
 635          parser = XMLParser(remove_pis=True) 
 636          tree = parse(f, parser) 
 637          self.assertEqual( 
 638              _bytes('<a><b><c/></b></a>'), 
 639              tostring(tree)) 
 640   
 642          # ET raises IOError only 
 643          parse = self.etree.parse 
 644          self.assertRaises(TypeError, parse, 'notthere.xml', object()) 
 645   
 647          # ET removes comments 
 648          iterparse = self.etree.iterparse 
 649          tostring = self.etree.tostring 
 650   
 651          f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 
 652          events = list(iterparse(f)) 
 653          root = events[-1][1] 
 654          self.assertEqual(3, len(events)) 
 655          self.assertEqual( 
 656              _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 
 657              tostring(root)) 
 658   
 660          # ET removes comments 
 661          iterparse = self.etree.iterparse 
 662          tostring = self.etree.tostring 
 663   
 664          def name(event, el): 
 665              if event == 'comment': 
 666                  return el.text 
 667              else: 
 668                  return el.tag 
 669   
 670          f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 
 671          events = list(iterparse(f, events=('end', 'comment'))) 
 672          root = events[-1][1] 
 673          self.assertEqual(6, len(events)) 
 674          self.assertEqual(['A', ' B ', 'c', 'b', 'C', 'a'], 
 675                            [ name(*item) for item in events ]) 
 676          self.assertEqual( 
 677              _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'), 
 678              tostring(root)) 
 679   
 681          # ET removes pis 
 682          iterparse = self.etree.iterparse 
 683          tostring = self.etree.tostring 
 684          ElementTree = self.etree.ElementTree 
 685   
 686          def name(event, el): 
 687              if event == 'pi': 
 688                  return (el.target, el.text) 
 689              else: 
 690                  return el.tag 
 691   
 692          f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>') 
 693          events = list(iterparse(f, events=('end', 'pi'))) 
 694          root = events[-2][1] 
 695          self.assertEqual(8, len(events)) 
 696          self.assertEqual([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b', 
 697                             ('pid','d'), 'a', ('pie','e')], 
 698                            [ name(*item) for item in events ]) 
 699          self.assertEqual( 
 700              _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'), 
 701              tostring(ElementTree(root))) 
 702   
 704          iterparse = self.etree.iterparse 
 705          tostring = self.etree.tostring 
 706   
 707          f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>') 
 708          events = list(iterparse(f, remove_comments=True, 
 709                                  events=('end', 'comment'))) 
 710          root = events[-1][1] 
 711          self.assertEqual(3, len(events)) 
 712          self.assertEqual(['c', 'b', 'a'], 
 713                            [ el.tag for (event, el) in events ]) 
 714          self.assertEqual( 
 715              _bytes('<a><b><c/></b></a>'), 
 716              tostring(root)) 
 717   
 719          iterparse = self.etree.iterparse 
 720          f = BytesIO('<a><b><c/></a>') 
 721          # ET raises ExpatError, lxml raises XMLSyntaxError 
 722          self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f)) 
 723   
 725          iterparse = self.etree.iterparse 
 726          f = BytesIO('<a><b><c/></a>') 
 727          it = iterparse(f, events=('start', 'end'), recover=True) 
 728          events = [(ev, el.tag) for ev, el in it] 
 729          root = it.root 
 730          self.assertTrue(root is not None) 
 731   
 732          self.assertEqual(1, events.count(('start', 'a'))) 
 733          self.assertEqual(1, events.count(('end', 'a'))) 
 734   
 735          self.assertEqual(1, events.count(('start', 'b'))) 
 736          self.assertEqual(1, events.count(('end', 'b'))) 
 737   
 738          self.assertEqual(1, events.count(('start', 'c'))) 
 739          self.assertEqual(1, events.count(('end', 'c'))) 
 740   
 742          iterparse = self.etree.iterparse 
 743          f = BytesIO('<a><b><c/></d><b><c/></a></b>') 
 744          it = iterparse(f, events=('start', 'end'), recover=True) 
 745          events = [(ev, el.tag) for ev, el in it] 
 746          root = it.root 
 747          self.assertTrue(root is not None) 
 748   
 749          self.assertEqual(1, events.count(('start', 'a'))) 
 750          self.assertEqual(1, events.count(('end', 'a'))) 
 751   
 752          self.assertEqual(2, events.count(('start', 'b'))) 
 753          self.assertEqual(2, events.count(('end', 'b'))) 
 754   
 755          self.assertEqual(2, events.count(('start', 'c'))) 
 756          self.assertEqual(2, events.count(('end', 'c'))) 
 757   
 759          iterparse = self.etree.iterparse 
 760          f = BytesIO(""" 
 761                 <a>  \n \n  <b> b test </b>  \n 
 762   
 763                 \n\t <c> \n </c> </a>  \n """) 
 764          iterator = iterparse(f, remove_blank_text=True) 
 765          text = [ (element.text, element.tail) 
 766                   for event, element in iterator ] 
 767          self.assertEqual( 
 768              [(" b test ", None), (" \n ", None), (None, None)], 
 769              text) 
 770   
 772          iterparse = self.etree.iterparse 
 773          f = BytesIO('<a><b><d/></b><c/></a>') 
 774   
 775          iterator = iterparse(f, tag="b", events=('start', 'end')) 
 776          events = list(iterator) 
 777          root = iterator.root 
 778          self.assertEqual( 
 779              [('start', root[0]), ('end', root[0])], 
 780              events) 
 781   
 783          iterparse = self.etree.iterparse 
 784          f = BytesIO('<a><b><d/></b><c/></a>') 
 785   
 786          iterator = iterparse(f, tag="*", events=('start', 'end')) 
 787          events = list(iterator) 
 788          self.assertEqual( 
 789              8, 
 790              len(events)) 
 791   
 793          iterparse = self.etree.iterparse 
 794          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 
 795   
 796          iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end')) 
 797          events = list(iterator) 
 798          root = iterator.root 
 799          self.assertEqual( 
 800              [('start', root[0]), ('end', root[0])], 
 801              events) 
 802   
 804          iterparse = self.etree.iterparse 
 805          f = BytesIO('<a><b><d/></b><c/></a>') 
 806          iterator = iterparse(f, tag="{}b", events=('start', 'end')) 
 807          events = list(iterator) 
 808          root = iterator.root 
 809          self.assertEqual( 
 810              [('start', root[0]), ('end', root[0])], 
 811              events) 
 812   
 813          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 
 814          iterator = iterparse(f, tag="{}b", events=('start', 'end')) 
 815          events = list(iterator) 
 816          root = iterator.root 
 817          self.assertEqual([], events) 
 818   
 820          iterparse = self.etree.iterparse 
 821          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 
 822          iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end')) 
 823          events = list(iterator) 
 824          self.assertEqual(8, len(events)) 
 825   
 827          iterparse = self.etree.iterparse 
 828          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>') 
 829          iterator = iterparse(f, tag="{}*", events=('start', 'end')) 
 830          events = list(iterator) 
 831          self.assertEqual([], events) 
 832   
 833          f = BytesIO('<a><b><d/></b><c/></a>') 
 834          iterator = iterparse(f, tag="{}*", events=('start', 'end')) 
 835          events = list(iterator) 
 836          self.assertEqual(8, len(events)) 
 837   
 839          text = _str('Søk på nettet') 
 840          wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 
 841          xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 
 842                        ).encode('iso-8859-1') 
 843   
 844          self.assertRaises(self.etree.ParseError, 
 845                            list, self.etree.iterparse(BytesIO(xml_latin1))) 
 846   
 848          text = _str('Søk på nettet', encoding="UTF-8") 
 849          wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>" 
 850          xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text) 
 851                        ).encode('iso-8859-1') 
 852   
 853          iterator = self.etree.iterparse(BytesIO(xml_latin1), 
 854                                          encoding="iso-8859-1") 
 855          self.assertEqual(1, len(list(iterator))) 
 856   
 857          a = iterator.root 
 858          self.assertEqual(a.text, text) 
 859   
 861          tostring = self.etree.tostring 
 862          f = BytesIO('<root><![CDATA[test]]></root>') 
 863          context = self.etree.iterparse(f, strip_cdata=False) 
 864          content = [ el.text for event,el in context ] 
 865   
 866          self.assertEqual(['test'], content) 
 867          self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 
 868                            tostring(context.root)) 
 869   
 873   
 875          self.etree.XMLParser(encoding="ascii") 
 876          self.etree.XMLParser(encoding="utf-8") 
 877          self.etree.XMLParser(encoding="iso-8859-1") 
 878   
 880          parser = self.etree.XMLParser(recover=True) 
 881   
 882          parser.feed('<?xml version=') 
 883          parser.feed('"1.0"?><ro') 
 884          parser.feed('ot><') 
 885          parser.feed('a test="works"') 
 886          parser.feed('><othertag/></root') # <a> not closed! 
 887          parser.feed('>') 
 888   
 889          root = parser.close() 
 890   
 891          self.assertEqual(root.tag, "root") 
 892          self.assertEqual(len(root), 1) 
 893          self.assertEqual(root[0].tag, "a") 
 894          self.assertEqual(root[0].get("test"), "works") 
 895          self.assertEqual(len(root[0]), 1) 
 896          self.assertEqual(root[0][0].tag, "othertag") 
 897          # FIXME: would be nice to get some errors logged ... 
 898          #self.assertTrue(len(parser.error_log) > 0, "error log is empty") 
 899   
 901          # test that recover mode plays nicely with the no-id-dict setup 
 902          parser = self.etree.XMLParser(recover=True, collect_ids=False) 
 903   
 904          parser.feed('<?xml version=') 
 905          parser.feed('"1.0"?><ro') 
 906          parser.feed('ot xml:id="123"><') 
 907          parser.feed('a test="works" xml:id=') 
 908          parser.feed('"321"><othertag/></root') # <a> not closed! 
 909          parser.feed('>') 
 910   
 911          root = parser.close() 
 912   
 913          self.assertEqual(root.tag, "root") 
 914          self.assertEqual(len(root), 1) 
 915          self.assertEqual(root[0].tag, "a") 
 916          self.assertEqual(root[0].get("test"), "works") 
 917          self.assertEqual(root[0].attrib, { 
 918              'test': 'works', 
 919              '{http://www.w3.org/XML/1998/namespace}id': '321'}) 
 920          self.assertEqual(len(root[0]), 1) 
 921          self.assertEqual(root[0][0].tag, "othertag") 
 922          # FIXME: would be nice to get some errors logged ... 
 923          #self.assertTrue(len(parser.error_log) > 0, "error log is empty") 
 924   
 926          assertEqual = self.assertEqual 
 927          assertFalse  = self.assertFalse 
 928   
 929          events = [] 
 930          class Target(object): 
 931              def start(self, tag, attrib): 
 932                  events.append("start") 
 933                  assertFalse(attrib) 
 934                  assertEqual("TAG", tag) 
 935              def end(self, tag): 
 936                  events.append("end") 
 937                  assertEqual("TAG", tag) 
 938              def close(self): 
 939                  return "DONE" # no Element! 
 940   
 941          parser = self.etree.XMLParser(target=Target()) 
 942          tree = self.etree.ElementTree() 
 943   
 944          self.assertRaises(TypeError, 
 945                            tree.parse, BytesIO("<TAG/>"), parser=parser) 
 946          self.assertEqual(["start", "end"], events) 
 947   
 949          # ET doesn't call .close() on errors 
 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                  if tag == 'a': 
 957                      raise ValueError("dead and gone") 
 958              def data(self, data): 
 959                  events.append("data-" + data) 
 960              def close(self): 
 961                  events.append("close") 
 962                  return "DONE" 
 963   
 964          parser = self.etree.XMLParser(target=Target()) 
 965   
 966          try: 
 967              parser.feed(_bytes('<root>A<a>ca</a>B</root>')) 
 968              done = parser.close() 
 969              self.fail("error expected, but parsing succeeded") 
 970          except ValueError: 
 971              done = 'value error received as expected' 
 972   
 973          self.assertEqual(["start-root", "data-A", "start-a", 
 974                             "data-ca", "end-a", "close"], 
 975                            events) 
 976   
 978          # ET doesn't call .close() on errors 
 979          events = [] 
 980          class Target(object): 
 981              def start(self, tag, attrib): 
 982                  events.append("start-" + tag) 
 983              def end(self, tag): 
 984                  events.append("end-" + tag) 
 985                  if tag == 'a': 
 986                      raise ValueError("dead and gone") 
 987              def data(self, data): 
 988                  events.append("data-" + data) 
 989              def close(self): 
 990                  events.append("close") 
 991                  return "DONE" 
 992   
 993          parser = self.etree.XMLParser(target=Target()) 
 994   
 995          try: 
 996              done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'), 
 997                                           parser=parser) 
 998              self.fail("error expected, but parsing succeeded") 
 999          except ValueError: 
1000              done = 'value error received as expected' 
1001   
1002          self.assertEqual(["start-root", "data-A", "start-a", 
1003                            "data-ca", "end-a", "close"], 
1004                           events) 
1005   
1007          # test that target parsing works nicely with the no-id-hash setup 
1008          events = [] 
1009          class Target(object): 
1010              def start(self, tag, attrib): 
1011                  events.append("start-" + tag) 
1012              def end(self, tag): 
1013                  events.append("end-" + tag) 
1014              def data(self, data): 
1015                  events.append("data-" + data) 
1016              def comment(self, text): 
1017                  events.append("comment-" + text) 
1018              def close(self): 
1019                  return "DONE" 
1020   
1021          parser = self.etree.XMLParser(target=Target(), collect_ids=False) 
1022   
1023          parser.feed(_bytes('<!--a--><root xml:id="123">A<!--b-->')) 
1024          parser.feed(_bytes('<sub xml:id="321"/>B</root>')) 
1025          done = parser.close() 
1026   
1027          self.assertEqual("DONE", done) 
1028          self.assertEqual(["comment-a", "start-root", "data-A", "comment-b", 
1029                            "start-sub", "end-sub", "data-B", "end-root"], 
1030                           events) 
1031   
1033          events = [] 
1034          class Target(object): 
1035              def start(self, tag, attrib): 
1036                  events.append("start-" + tag) 
1037              def end(self, tag): 
1038                  events.append("end-" + tag) 
1039              def data(self, data): 
1040                  events.append("data-" + data) 
1041              def comment(self, text): 
1042                  events.append("comment-" + text) 
1043              def close(self): 
1044                  return "DONE" 
1045   
1046          parser = self.etree.XMLParser(target=Target()) 
1047   
1048          parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->')) 
1049          done = parser.close() 
1050   
1051          self.assertEqual("DONE", done) 
1052          self.assertEqual(["comment-a", "start-root", "data-A", "comment-b", 
1053                             "start-sub", "end-sub", "comment-c", "data-B", 
1054                             "end-root", "comment-d"], 
1055                            events) 
1056   
1058          events = [] 
1059          class Target(object): 
1060              def start(self, tag, attrib): 
1061                  events.append("start-" + tag) 
1062              def end(self, tag): 
1063                  events.append("end-" + tag) 
1064              def data(self, data): 
1065                  events.append("data-" + data) 
1066              def pi(self, target, data): 
1067                  events.append("pi-" + target + "-" + data) 
1068              def close(self): 
1069                  return "DONE" 
1070   
1071          parser = self.etree.XMLParser(target=Target()) 
1072   
1073          parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>')) 
1074          done = parser.close() 
1075   
1076          self.assertEqual("DONE", done) 
1077          self.assertEqual(["pi-test-a", "start-root", "data-A", "pi-test-b", 
1078                             "data-B", "end-root", "pi-test-c"], 
1079                            events) 
1080   
1082          events = [] 
1083          class Target(object): 
1084              def start(self, tag, attrib): 
1085                  events.append("start-" + tag) 
1086              def end(self, tag): 
1087                  events.append("end-" + tag) 
1088              def data(self, data): 
1089                  events.append("data-" + data) 
1090              def close(self): 
1091                  return "DONE" 
1092   
1093          parser = self.etree.XMLParser(target=Target(), 
1094                                        strip_cdata=False) 
1095   
1096          parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>')) 
1097          done = parser.close() 
1098   
1099          self.assertEqual("DONE", done) 
1100          self.assertEqual(["start-root", "data-A", "start-a", 
1101                             "data-ca", "end-a", "data-B", "end-root"], 
1102                            events) 
1103   
1105          events = [] 
1106          class Target(object): 
1107              def start(self, tag, attrib): 
1108                  events.append("start-" + tag) 
1109              def end(self, tag): 
1110                  events.append("end-" + tag) 
1111              def data(self, data): 
1112                  events.append("data-" + data) 
1113              def close(self): 
1114                  events.append("close") 
1115                  return "DONE" 
1116   
1117          parser = self.etree.XMLParser(target=Target(), 
1118                                        recover=True) 
1119   
1120          parser.feed(_bytes('<root>A<a>ca</a>B</not-root>')) 
1121          done = parser.close() 
1122   
1123          self.assertEqual("DONE", done) 
1124          self.assertEqual(["start-root", "data-A", "start-a", 
1125                             "data-ca", "end-a", "data-B", 
1126                             "end-root", "close"], 
1127                            events) 
1128   
1130          iterwalk = self.etree.iterwalk 
1131          root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 
1132   
1133          iterator = iterwalk(root, tag="b", events=('start', 'end')) 
1134          events = list(iterator) 
1135          self.assertEqual( 
1136              [('start', root[0]), ('end', root[0])], 
1137              events) 
1138   
1140          iterwalk = self.etree.iterwalk 
1141          root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 
1142   
1143          iterator = iterwalk(root, tag="*", events=('start', 'end')) 
1144          events = list(iterator) 
1145          self.assertEqual( 
1146              8, 
1147              len(events)) 
1148   
1150          iterwalk = self.etree.iterwalk 
1151          root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 
1152   
1153          events = list(iterwalk(root)) 
1154          self.assertEqual( 
1155              [('end', root[0]), ('end', root[1]), ('end', root)], 
1156              events) 
1157   
1159          iterwalk = self.etree.iterwalk 
1160          root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 
1161   
1162          iterator = iterwalk(root, events=('start',)) 
1163          events = list(iterator) 
1164          self.assertEqual( 
1165              [('start', root), ('start', root[0]), ('start', root[1])], 
1166              events) 
1167   
1169          iterwalk = self.etree.iterwalk 
1170          root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 
1171   
1172          iterator = iterwalk(root, events=('start','end')) 
1173          events = list(iterator) 
1174          self.assertEqual( 
1175              [('start', root), ('start', root[0]), ('end', root[0]), 
1176               ('start', root[1]), ('end', root[1]), ('end', root)], 
1177              events) 
1178   
1180          iterwalk = self.etree.iterwalk 
1181          root = self.etree.XML(_bytes('<a><b></b><c/></a>')) 
1182   
1183          iterator = iterwalk(root) 
1184          for event, elem in iterator: 
1185              elem.clear() 
1186   
1187          self.assertEqual(0, 
1188                            len(root)) 
1189   
1191          iterwalk = self.etree.iterwalk 
1192          root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>')) 
1193   
1194          attr_name = '{testns}bla' 
1195          events = [] 
1196          iterator = iterwalk(root, events=('start','end','start-ns','end-ns')) 
1197          for event, elem in iterator: 
1198              events.append(event) 
1199              if event == 'start': 
1200                  if elem.tag != '{ns1}a': 
1201                      elem.set(attr_name, 'value') 
1202   
1203          self.assertEqual( 
1204              ['start-ns', 'start', 'start', 'start-ns', 'start', 
1205               'end', 'end-ns', 'end', 'end', 'end-ns'], 
1206              events) 
1207   
1208          self.assertEqual( 
1209              None, 
1210              root.get(attr_name)) 
1211          self.assertEqual( 
1212              'value', 
1213              root[0].get(attr_name)) 
1214   
1216          iterwalk = self.etree.iterwalk 
1217          root = self.etree.XML(_bytes('<a><b><c/></b><d><e/></d></a>')) 
1218   
1219          iterator = iterwalk(root) 
1220          tags = [] 
1221          for event, elem in iterator: 
1222              tags.append(elem.tag) 
1223              # requesting a skip after an 'end' event should never have an effect 
1224              iterator.skip_subtree() 
1225   
1226          self.assertEqual(['c', 'b', 'e', 'd', 'a'], tags) 
1227   
1229          iterwalk = self.etree.iterwalk 
1230          root = self.etree.XML(_bytes('<a><b><c/></b><d><e/></d></a>')) 
1231   
1232          iterator = iterwalk(root, events=('start', 'end')) 
1233          tags = [] 
1234          for event, elem in iterator: 
1235              tags.append((event, elem.tag)) 
1236              if elem.tag in ('b', 'e'): 
1237                  # skipping should only have an effect on 'start', not on 'end' 
1238                  iterator.skip_subtree() 
1239   
1240          self.assertEqual( 
1241              [('start', 'a'), 
1242               ('start', 'b'), ('end', 'b'),  # ignored child 'c' 
1243               ('start', 'd'), 
1244               ('start', 'e'), ('end', 'e'), 
1245               ('end', 'd'), 
1246               ('end', 'a')], 
1247              tags) 
1248   
1250          iterwalk = self.etree.iterwalk 
1251          root = self.etree.XML(_bytes( 
1252              '<a xmlns="ns1"><b xmlns="nsb"><c xmlns="ns2"/></b><d xmlns="ns2"><e/></d></a>')) 
1253   
1254          events = [] 
1255          iterator = iterwalk(root, events=('start','start-ns','end-ns')) 
1256          for event, elem in iterator: 
1257              if event in ('start-ns', 'end-ns'): 
1258                  events.append((event, elem)) 
1259                  if event == 'start-ns' and elem == ('', 'nsb'): 
1260                      events.append('skip') 
1261                      iterator.skip_subtree() 
1262              else: 
1263                  events.append((event, elem.tag)) 
1264   
1265          self.assertEqual( 
1266              [('start-ns', ('', 'ns1')), 
1267               ('start', '{ns1}a'), 
1268               ('start-ns', ('', 'nsb')), 
1269               'skip', 
1270               ('start', '{nsb}b'), 
1271               ('end-ns', None), 
1272               ('start-ns', ('', 'ns2')), 
1273               ('start', '{ns2}d'), 
1274               ('start', '{ns2}e'), 
1275               ('end-ns', None), 
1276               ('end-ns', None) 
1277               ], 
1278              events) 
1279   
1281          iterwalk = self.etree.iterwalk 
1282          root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>')) 
1283   
1284          counts = [] 
1285          for event, elem in iterwalk(root): 
1286              counts.append(len(list(elem.getiterator()))) 
1287          self.assertEqual( 
1288              [1,2,1,4], 
1289              counts) 
1290   
1292          parse = self.etree.parse 
1293          parser = self.etree.XMLParser(dtd_validation=True) 
1294          assertEqual = self.assertEqual 
1295          test_url = _str("__nosuch.dtd") 
1296   
1297          class MyResolver(self.etree.Resolver): 
1298              def resolve(self, url, id, context): 
1299                  assertEqual(url, test_url) 
1300                  return self.resolve_string( 
1301                      _str('''<!ENTITY myentity "%s"> 
1302                          <!ELEMENT doc ANY>''') % url, context) 
1303   
1304          parser.resolvers.add(MyResolver()) 
1305   
1306          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 
1307          tree = parse(StringIO(xml), parser) 
1308          root = tree.getroot() 
1309          self.assertEqual(root.text, test_url) 
1310   
1312          parse = self.etree.parse 
1313          parser = self.etree.XMLParser(dtd_validation=True) 
1314          assertEqual = self.assertEqual 
1315          test_url = _str("__nosuch.dtd") 
1316   
1317          class MyResolver(self.etree.Resolver): 
1318              def resolve(self, url, id, context): 
1319                  assertEqual(url, test_url) 
1320                  return self.resolve_string( 
1321                      (_str('''<!ENTITY myentity "%s"> 
1322                               <!ELEMENT doc ANY>''') % url).encode('utf-8'), 
1323                      context) 
1324   
1325          parser.resolvers.add(MyResolver()) 
1326   
1327          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 
1328          tree = parse(StringIO(xml), parser) 
1329          root = tree.getroot() 
1330          self.assertEqual(root.text, test_url) 
1331   
1333          parse = self.etree.parse 
1334          parser = self.etree.XMLParser(dtd_validation=True) 
1335          assertEqual = self.assertEqual 
1336          test_url = _str("__nosuch.dtd") 
1337   
1338          class MyResolver(self.etree.Resolver): 
1339              def resolve(self, url, id, context): 
1340                  assertEqual(url, test_url) 
1341                  return self.resolve_file( 
1342                      SillyFileLike( 
1343                          _str('''<!ENTITY myentity "%s"> 
1344                          <!ELEMENT doc ANY>''') % url), context) 
1345   
1346          parser.resolvers.add(MyResolver()) 
1347   
1348          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 
1349          tree = parse(StringIO(xml), parser) 
1350          root = tree.getroot() 
1351          self.assertEqual(root.text, test_url) 
1352   
1354          parse = self.etree.parse 
1355          parser = self.etree.XMLParser(attribute_defaults=True) 
1356          assertEqual = self.assertEqual 
1357          test_url = _str("__nosuch.dtd") 
1358   
1359          class MyResolver(self.etree.Resolver): 
1360              def resolve(self, url, id, context): 
1361                  assertEqual(url, test_url) 
1362                  return self.resolve_filename( 
1363                      fileInTestDir('test.dtd'), context) 
1364   
1365          parser.resolvers.add(MyResolver()) 
1366   
1367          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 
1368          tree = parse(StringIO(xml), parser) 
1369          root = tree.getroot() 
1370          self.assertEqual( 
1371              root.attrib,    {'default': 'valueA'}) 
1372          self.assertEqual( 
1373              root[0].attrib, {'default': 'valueB'}) 
1374   
1376          parse = self.etree.parse 
1377          parser = self.etree.XMLParser(attribute_defaults=True) 
1378          assertEqual = self.assertEqual 
1379          test_url = _str("__nosuch.dtd") 
1380   
1381          class MyResolver(self.etree.Resolver): 
1382              def resolve(self, url, id, context): 
1383                  expected = fileUrlInTestDir(test_url) 
1384                  url = url.replace('file://', 'file:')  # depends on libxml2 version 
1385                  expected = expected.replace('file://', 'file:') 
1386                  assertEqual(url, expected) 
1387                  return self.resolve_filename( 
1388                      fileUrlInTestDir('test.dtd'), context) 
1389   
1390          parser.resolvers.add(MyResolver()) 
1391   
1392          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 
1393          tree = parse(StringIO(xml), parser, 
1394                       base_url=fileUrlInTestDir('__test.xml')) 
1395          root = tree.getroot() 
1396          self.assertEqual( 
1397              root.attrib,    {'default': 'valueA'}) 
1398          self.assertEqual( 
1399              root[0].attrib, {'default': 'valueB'}) 
1400   
1402          parse = self.etree.parse 
1403          parser = self.etree.XMLParser(attribute_defaults=True) 
1404          assertEqual = self.assertEqual 
1405          test_url = _str("__nosuch.dtd") 
1406   
1407          class MyResolver(self.etree.Resolver): 
1408              def resolve(self, url, id, context): 
1409                  assertEqual(url, test_url) 
1410                  return self.resolve_file( 
1411                      open(fileInTestDir('test.dtd'), 'rb'), context) 
1412   
1413          parser.resolvers.add(MyResolver()) 
1414   
1415          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 
1416          tree = parse(StringIO(xml), parser) 
1417          root = tree.getroot() 
1418          self.assertEqual( 
1419              root.attrib,    {'default': 'valueA'}) 
1420          self.assertEqual( 
1421              root[0].attrib, {'default': 'valueB'}) 
1422   
1424          parse = self.etree.parse 
1425          parser = self.etree.XMLParser(load_dtd=True) 
1426          assertEqual = self.assertEqual 
1427          test_url = _str("__nosuch.dtd") 
1428   
1429          class check(object): 
1430              resolved = False 
1431   
1432          class MyResolver(self.etree.Resolver): 
1433              def resolve(self, url, id, context): 
1434                  assertEqual(url, test_url) 
1435                  check.resolved = True 
1436                  return self.resolve_empty(context) 
1437   
1438          parser.resolvers.add(MyResolver()) 
1439   
1440          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 
1441          self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser) 
1442          self.assertTrue(check.resolved) 
1443   
1445          parse = self.etree.parse 
1446          parser = self.etree.XMLParser(dtd_validation=True) 
1447   
1448          class _LocalException(Exception): 
1449              pass 
1450   
1451          class MyResolver(self.etree.Resolver): 
1452              def resolve(self, url, id, context): 
1453                  raise _LocalException 
1454   
1455          parser.resolvers.add(MyResolver()) 
1456   
1457          xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 
1458          self.assertRaises(_LocalException, parse, BytesIO(xml), parser) 
1459   
1460      if etree.LIBXML_VERSION > (2,6,20): 
1462              parse = self.etree.parse 
1463              tostring = self.etree.tostring 
1464              parser = self.etree.XMLParser(resolve_entities=False) 
1465              Entity = self.etree.Entity 
1466   
1467              xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>') 
1468              tree = parse(BytesIO(xml), parser) 
1469              root = tree.getroot() 
1470              self.assertEqual(root[0].tag, Entity) 
1471              self.assertEqual(root[0].text, "&myentity;") 
1472              self.assertEqual(root[0].tail, None) 
1473              self.assertEqual(root[0].name, "myentity") 
1474   
1475              self.assertEqual(_bytes('<doc>&myentity;</doc>'), 
1476                                tostring(root)) 
1477   
1479              xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]> 
1480                  <root> 
1481                    <child1/> 
1482                    <child2/> 
1483                    <child3> </child3> 
1484                  </root>''') 
1485   
1486              parser = self.etree.XMLParser(resolve_entities=False) 
1487              root = etree.fromstring(xml, parser) 
1488              self.assertEqual([ el.tag for el in root ], 
1489                                ['child1', 'child2', 'child3']) 
1490   
1491              root[0] = root[-1] 
1492              self.assertEqual([ el.tag for el in root ], 
1493                                ['child3', 'child2']) 
1494              self.assertEqual(root[0][0].text, ' ') 
1495              self.assertEqual(root[0][0].name, 'nbsp') 
1496   
1498          Entity = self.etree.Entity 
1499          Element = self.etree.Element 
1500          tostring = self.etree.tostring 
1501   
1502          root = Element("root") 
1503          root.append( Entity("test") ) 
1504   
1505          self.assertEqual(root[0].tag, Entity) 
1506          self.assertEqual(root[0].text, "&test;") 
1507          self.assertEqual(root[0].tail, None) 
1508          self.assertEqual(root[0].name, "test") 
1509   
1510          self.assertEqual(_bytes('<root>&test;</root>'), 
1511                            tostring(root)) 
1512   
1514          Entity = self.etree.Entity 
1515          self.assertEqual(Entity("test").text, '&test;') 
1516          self.assertEqual(Entity("#17683").text, '䔓') 
1517          self.assertEqual(Entity("#x1768").text, 'ᝨ') 
1518          self.assertEqual(Entity("#x98AF").text, '颯') 
1519   
1521          Entity = self.etree.Entity 
1522          self.assertRaises(ValueError, Entity, 'a b c') 
1523          self.assertRaises(ValueError, Entity, 'a,b') 
1524          self.assertRaises(ValueError, Entity, 'a\0b') 
1525          self.assertRaises(ValueError, Entity, '#abc') 
1526          self.assertRaises(ValueError, Entity, '#xxyz') 
1527   
1529          CDATA = self.etree.CDATA 
1530          Element = self.etree.Element 
1531          tostring = self.etree.tostring 
1532   
1533          root = Element("root") 
1534          root.text = CDATA('test') 
1535   
1536          self.assertEqual('test', 
1537                            root.text) 
1538          self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 
1539                            tostring(root)) 
1540   
1542          CDATA = self.etree.CDATA 
1543          Element = self.etree.Element 
1544          SubElement = self.etree.SubElement 
1545          tostring = self.etree.tostring 
1546   
1547          root = Element("root") 
1548          child = SubElement(root, 'child') 
1549          child.tail = CDATA('test') 
1550   
1551          self.assertEqual('test', child.tail) 
1552          self.assertEqual(_bytes('<root><child/><![CDATA[test]]></root>'), 
1553                           tostring(root)) 
1554   
1555          root = Element("root") 
1556          root.tail = CDATA('test') 
1557   
1558          self.assertEqual('test', root.tail) 
1559          self.assertEqual(_bytes('<root/><![CDATA[test]]>'), 
1560                           tostring(root)) 
1561   
1563          CDATA = self.etree.CDATA 
1564          Element = self.etree.Element 
1565          root = Element("root") 
1566   
1567          root.text = CDATA("test") 
1568          self.assertEqual('test', root.text) 
1569   
1570          root.text = CDATA(_str("test")) 
1571          self.assertEqual('test', root.text) 
1572   
1573          self.assertRaises(TypeError, CDATA, 1) 
1574   
1576          CDATA = self.etree.CDATA 
1577          Element = self.etree.Element 
1578   
1579          root = Element("root") 
1580          cdata = CDATA('test') 
1581   
1582          self.assertRaises(TypeError, 
1583                            root.set, 'attr', cdata) 
1584          self.assertRaises(TypeError, 
1585                            operator.setitem, root.attrib, 'attr', cdata) 
1586   
1588          tostring = self.etree.tostring 
1589          parser = self.etree.XMLParser(strip_cdata=False) 
1590          root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 
1591   
1592          self.assertEqual('test', root.text) 
1593          self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 
1594                            tostring(root)) 
1595   
1597          tostring = self.etree.tostring 
1598          parser = self.etree.XMLParser(strip_cdata=False) 
1599          root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 
1600          self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 
1601                            tostring(root)) 
1602   
1603          self.assertEqual(['test'], root.xpath('//text()')) 
1604   
1605      # TypeError in etree, AssertionError in ElementTree; 
1607          Element = self.etree.Element 
1608          SubElement = self.etree.SubElement 
1609   
1610          a = Element('a') 
1611          b = SubElement(a, 'b') 
1612           
1613          self.assertRaises(TypeError, 
1614                            a.__setitem__, 0, 'foo') 
1615   
1617          Element = self.etree.Element 
1618          root = Element('root') 
1619          # raises AssertionError in ElementTree 
1620          self.assertRaises(TypeError, root.append, None) 
1621          self.assertRaises(TypeError, root.extend, [None]) 
1622          self.assertRaises(TypeError, root.extend, [Element('one'), None]) 
1623          self.assertEqual('one', root[0].tag) 
1624   
1626          Element = self.etree.Element 
1627          SubElement = self.etree.SubElement 
1628          root = Element('root') 
1629          self.assertRaises(ValueError, root.append, root) 
1630          child = SubElement(root, 'child') 
1631          self.assertRaises(ValueError, child.append, root) 
1632          child2 = SubElement(child, 'child2') 
1633          self.assertRaises(ValueError, child2.append, root) 
1634          self.assertRaises(ValueError, child2.append, child) 
1635          self.assertEqual('child2', root[0][0].tag) 
1636   
1638          Element = self.etree.Element 
1639          SubElement = self.etree.SubElement 
1640          root = Element('root') 
1641          SubElement(root, 'a') 
1642          SubElement(root, 'b') 
1643   
1644          self.assertEqual(['a', 'b'], 
1645                            [c.tag for c in root]) 
1646          root[1].addnext(root[0]) 
1647          self.assertEqual(['b', 'a'], 
1648                            [c.tag for c in root]) 
1649   
1651          Element = self.etree.Element 
1652          SubElement = self.etree.SubElement 
1653          root = Element('root') 
1654          SubElement(root, 'a') 
1655          SubElement(root, 'b') 
1656   
1657          self.assertEqual(['a', 'b'], 
1658                            [c.tag for c in root]) 
1659          root[0].addprevious(root[1]) 
1660          self.assertEqual(['b', 'a'], 
1661                            [c.tag for c in root]) 
1662   
1664          Element = self.etree.Element 
1665          SubElement = self.etree.SubElement 
1666          root = Element('root') 
1667          a = SubElement(root, 'a') 
1668          b = SubElement(a, 'b') 
1669          # appending parent as sibling is forbidden 
1670          self.assertRaises(ValueError, b.addnext, a) 
1671          self.assertEqual(['a'], [c.tag for c in root]) 
1672          self.assertEqual(['b'], [c.tag for c in a]) 
1673   
1675          Element = self.etree.Element 
1676          SubElement = self.etree.SubElement 
1677          root = Element('root') 
1678          a = SubElement(root, 'a') 
1679          b = SubElement(a, 'b') 
1680          # appending parent as sibling is forbidden 
1681          self.assertRaises(ValueError, b.addprevious, a) 
1682          self.assertEqual(['a'], [c.tag for c in root]) 
1683          self.assertEqual(['b'], [c.tag for c in a]) 
1684   
1686          Element = self.etree.Element 
1687          SubElement = self.etree.SubElement 
1688          root = Element('root') 
1689          a = SubElement(root, 'a') 
1690          b = SubElement(a, 'b') 
1691          c = SubElement(b, 'c') 
1692          # appending parent as sibling is forbidden 
1693          self.assertRaises(ValueError, c.addnext, a) 
1694   
1696          Element = self.etree.Element 
1697          SubElement = self.etree.SubElement 
1698          root = Element('root') 
1699          a = SubElement(root, 'a') 
1700          b = SubElement(a, 'b') 
1701          c = SubElement(b, 'c') 
1702          # appending parent as sibling is forbidden 
1703          self.assertRaises(ValueError, c.addprevious, a) 
1704   
1706          Element = self.etree.Element 
1707          SubElement = self.etree.SubElement 
1708          root = Element('root') 
1709          a = SubElement(root, 'a') 
1710          b = SubElement(root, 'b') 
1711          a.addprevious(a) 
1712          self.assertEqual('a', root[0].tag) 
1713          self.assertEqual('b', root[1].tag) 
1714          b.addprevious(b) 
1715          self.assertEqual('a', root[0].tag) 
1716          self.assertEqual('b', root[1].tag) 
1717          b.addprevious(a) 
1718          self.assertEqual('a', root[0].tag) 
1719          self.assertEqual('b', root[1].tag) 
1720   
1722          Element = self.etree.Element 
1723          SubElement = self.etree.SubElement 
1724          root = Element('root') 
1725          a = SubElement(root, 'a') 
1726          b = SubElement(root, 'b') 
1727          a.addnext(a) 
1728          self.assertEqual('a', root[0].tag) 
1729          self.assertEqual('b', root[1].tag) 
1730          b.addnext(b) 
1731          self.assertEqual('a', root[0].tag) 
1732          self.assertEqual('b', root[1].tag) 
1733          a.addnext(b) 
1734          self.assertEqual('a', root[0].tag) 
1735          self.assertEqual('b', root[1].tag) 
1736   
1738          Element = self.etree.Element 
1739          a = Element('a') 
1740          b = Element('b') 
1741          self.assertRaises(TypeError, a.addnext, b) 
1742   
1744          Element = self.etree.Element 
1745          SubElement = self.etree.SubElement 
1746          PI = self.etree.PI 
1747          root = Element('root') 
1748          SubElement(root, 'a') 
1749          pi = PI('TARGET', 'TEXT') 
1750          pi.tail = "TAIL" 
1751   
1752          self.assertEqual(_bytes('<root><a></a></root>'), 
1753                            self._writeElement(root)) 
1754          root[0].addprevious(pi) 
1755          self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'), 
1756                            self._writeElement(root)) 
1757   
1759          Element = self.etree.Element 
1760          PI = self.etree.PI 
1761          root = Element('root') 
1762          pi = PI('TARGET', 'TEXT') 
1763          pi.tail = "TAIL" 
1764   
1765          self.assertEqual(_bytes('<root></root>'), 
1766                            self._writeElement(root)) 
1767          root.addprevious(pi) 
1768          self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'), 
1769                            self._writeElement(root)) 
1770   
1772          Element = self.etree.Element 
1773          SubElement = self.etree.SubElement 
1774          PI = self.etree.PI 
1775          root = Element('root') 
1776          SubElement(root, 'a') 
1777          pi = PI('TARGET', 'TEXT') 
1778          pi.tail = "TAIL" 
1779   
1780          self.assertEqual(_bytes('<root><a></a></root>'), 
1781                            self._writeElement(root)) 
1782          root[0].addnext(pi) 
1783          self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'), 
1784                            self._writeElement(root)) 
1785   
1787          Element = self.etree.Element 
1788          PI = self.etree.PI 
1789          root = Element('root') 
1790          pi = PI('TARGET', 'TEXT') 
1791          pi.tail = "TAIL" 
1792   
1793          self.assertEqual(_bytes('<root></root>'), 
1794                            self._writeElement(root)) 
1795          root.addnext(pi) 
1796          self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'), 
1797                            self._writeElement(root)) 
1798   
1800          Element = self.etree.Element 
1801          SubElement = self.etree.SubElement 
1802          Comment = self.etree.Comment 
1803          root = Element('root') 
1804          SubElement(root, 'a') 
1805          comment = Comment('TEXT ') 
1806          comment.tail = "TAIL" 
1807   
1808          self.assertEqual(_bytes('<root><a></a></root>'), 
1809                            self._writeElement(root)) 
1810          root[0].addnext(comment) 
1811          self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'), 
1812                            self._writeElement(root)) 
1813   
1815          Element = self.etree.Element 
1816          Comment = self.etree.Comment 
1817          root = Element('root') 
1818          comment = Comment('TEXT ') 
1819          comment.tail = "TAIL" 
1820   
1821          self.assertEqual(_bytes('<root></root>'), 
1822                            self._writeElement(root)) 
1823          root.addnext(comment) 
1824          self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'), 
1825                            self._writeElement(root)) 
1826   
1828          Element = self.etree.Element 
1829          SubElement = self.etree.SubElement 
1830          Comment = self.etree.Comment 
1831          root = Element('root') 
1832          SubElement(root, 'a') 
1833          comment = Comment('TEXT ') 
1834          comment.tail = "TAIL" 
1835   
1836          self.assertEqual(_bytes('<root><a></a></root>'), 
1837                            self._writeElement(root)) 
1838          root[0].addprevious(comment) 
1839          self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'), 
1840                            self._writeElement(root)) 
1841   
1843          Element = self.etree.Element 
1844          Comment = self.etree.Comment 
1845          root = Element('root') 
1846          comment = Comment('TEXT ') 
1847          comment.tail = "TAIL" 
1848   
1849          self.assertEqual(_bytes('<root></root>'), 
1850                            self._writeElement(root)) 
1851          root.addprevious(comment) 
1852          self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'), 
1853                            self._writeElement(root)) 
1854   
1855      # ET's Elements have items() and key(), but not values() 
1857          XML = self.etree.XML 
1858           
1859          root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')) 
1860          values = root.values() 
1861          values.sort() 
1862          self.assertEqual(['Alpha', 'Beta', 'Gamma'], values) 
1863   
1864      # gives error in ElementTree 
1866          Element = self.etree.Element 
1867          Comment = self.etree.Comment 
1868   
1869          a = Element('a') 
1870          a.append(Comment()) 
1871          self.assertEqual( 
1872              _bytes('<a><!----></a>'), 
1873              self._writeElement(a)) 
1874   
1875      # ElementTree ignores comments 
1877          ElementTree = self.etree.ElementTree 
1878          tostring = self.etree.tostring 
1879   
1880          xml = _bytes('<a><b/><!----><c/></a>') 
1881          f = BytesIO(xml) 
1882          doc = ElementTree(file=f) 
1883          a = doc.getroot() 
1884          self.assertEqual( 
1885              '', 
1886              a[1].text) 
1887          self.assertEqual( 
1888              xml, 
1889              tostring(a)) 
1890   
1891      # ElementTree ignores comments 
1893          ElementTree = self.etree.ElementTree 
1894           
1895          f = BytesIO('<a><b></b><!-- hoi --><c></c></a>') 
1896          doc = ElementTree(file=f) 
1897          a = doc.getroot() 
1898          self.assertEqual( 
1899              ' hoi ', 
1900              a[1].text) 
1901   
1902      # does not raise an exception in ElementTree 
1904          Element = self.etree.Element 
1905          Comment = self.etree.Comment 
1906   
1907          c = Comment() 
1908          el = Element('myel') 
1909   
1910          self.assertRaises(TypeError, c.append, el) 
1911          self.assertRaises(TypeError, c.insert, 0, el) 
1912          self.assertRaises(TypeError, c.set, "myattr", "test") 
1913   
1915          c = self.etree.Comment() 
1916          self.assertEqual(0, len(c.attrib)) 
1917   
1918          self.assertFalse(c.attrib.__contains__('nope')) 
1919          self.assertFalse('nope' in c.attrib) 
1920          self.assertFalse('nope' in c.attrib.keys()) 
1921          self.assertFalse('nope' in c.attrib.values()) 
1922          self.assertFalse(('nope', 'huhu') in c.attrib.items()) 
1923   
1924          self.assertEqual([], list(c.attrib)) 
1925          self.assertEqual([], list(c.attrib.keys())) 
1926          self.assertEqual([], list(c.attrib.items())) 
1927          self.assertEqual([], list(c.attrib.values())) 
1928          self.assertEqual([], list(c.attrib.iterkeys())) 
1929          self.assertEqual([], list(c.attrib.iteritems())) 
1930          self.assertEqual([], list(c.attrib.itervalues())) 
1931   
1932          self.assertEqual('HUHU', c.attrib.pop('nope', 'HUHU')) 
1933          self.assertRaises(KeyError, c.attrib.pop, 'nope') 
1934   
1935          self.assertRaises(KeyError, c.attrib.__getitem__, 'only') 
1936          self.assertRaises(KeyError, c.attrib.__getitem__, 'names') 
1937          self.assertRaises(KeyError, c.attrib.__getitem__, 'nope') 
1938          self.assertRaises(KeyError, c.attrib.__setitem__, 'nope', 'yep') 
1939          self.assertRaises(KeyError, c.attrib.__delitem__, 'nope') 
1940   
1941      # test passing 'None' to dump() 
1944   
1946          ElementTree = self.etree.ElementTree 
1947           
1948          f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 
1949          doc = ElementTree(file=f) 
1950          a = doc.getroot() 
1951          self.assertEqual( 
1952              None, 
1953              a.prefix) 
1954          self.assertEqual( 
1955              'foo', 
1956              a[0].prefix) 
1957   
1959          ElementTree = self.etree.ElementTree 
1960           
1961          f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 
1962          doc = ElementTree(file=f) 
1963          a = doc.getroot() 
1964          self.assertEqual( 
1965              None, 
1966              a.prefix) 
1967          self.assertEqual( 
1968              None, 
1969              a[0].prefix) 
1970   
1972          Element = self.etree.Element 
1973          SubElement = self.etree.SubElement 
1974   
1975          a = Element('a') 
1976          b = SubElement(a, 'b') 
1977          c = SubElement(a, 'c') 
1978          d = SubElement(b, 'd') 
1979          self.assertEqual( 
1980              None, 
1981              a.getparent()) 
1982          self.assertEqual( 
1983              a, 
1984              b.getparent()) 
1985          self.assertEqual( 
1986              b.getparent(), 
1987              c.getparent()) 
1988          self.assertEqual( 
1989              b, 
1990              d.getparent()) 
1991   
1993          XML = self.etree.XML 
1994           
1995          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 
1996          result = [] 
1997          for el in root.iterchildren(): 
1998              result.append(el.tag) 
1999          self.assertEqual(['one', 'two', 'three'], result) 
2000   
2002          XML = self.etree.XML 
2003           
2004          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 
2005          result = [] 
2006          for el in root.iterchildren(reversed=True): 
2007              result.append(el.tag) 
2008          self.assertEqual(['three', 'two', 'one'], result) 
2009   
2011          XML = self.etree.XML 
2012           
2013          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 
2014          result = [] 
2015          for el in root.iterchildren(tag='two'): 
2016              result.append(el.text) 
2017          self.assertEqual(['Two', 'Bla'], result) 
2018   
2020          XML = self.etree.XML 
2021   
2022          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 
2023          result = [] 
2024          for el in root.iterchildren('two'): 
2025              result.append(el.text) 
2026          self.assertEqual(['Two', 'Bla'], result) 
2027   
2029          XML = self.etree.XML 
2030           
2031          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 
2032          result = [] 
2033          for el in root.iterchildren(reversed=True, tag='two'): 
2034              result.append(el.text) 
2035          self.assertEqual(['Bla', 'Two'], result) 
2036   
2038          XML = self.etree.XML 
2039   
2040          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 
2041          result = [] 
2042          for el in root.iterchildren(tag=['two', 'three']): 
2043              result.append(el.text) 
2044          self.assertEqual(['Two', 'Bla', None], result) 
2045   
2047          XML = self.etree.XML 
2048   
2049          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 
2050          result = [] 
2051          for el in root.iterchildren('two', 'three'): 
2052              result.append(el.text) 
2053          self.assertEqual(['Two', 'Bla', None], result) 
2054   
2056          XML = self.etree.XML 
2057   
2058          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 
2059          result = [] 
2060          for el in root.iterchildren(reversed=True, tag=['two', 'three']): 
2061              result.append(el.text) 
2062          self.assertEqual([None, 'Bla', 'Two'], result) 
2063   
2065          Element    = self.etree.Element 
2066          SubElement = self.etree.SubElement 
2067   
2068          a = Element('a') 
2069          b = SubElement(a, 'b') 
2070          c = SubElement(a, 'c') 
2071          d = SubElement(b, 'd') 
2072          self.assertEqual( 
2073              [], 
2074              list(a.iterancestors())) 
2075          self.assertEqual( 
2076              [a], 
2077              list(b.iterancestors())) 
2078          self.assertEqual( 
2079              [a], 
2080              list(c.iterancestors())) 
2081          self.assertEqual( 
2082              [b, a], 
2083              list(d.iterancestors())) 
2084   
2086          Element    = self.etree.Element 
2087          SubElement = self.etree.SubElement 
2088   
2089          a = Element('a') 
2090          b = SubElement(a, 'b') 
2091          c = SubElement(a, 'c') 
2092          d = SubElement(b, 'd') 
2093          self.assertEqual( 
2094              [a], 
2095              list(d.iterancestors('a'))) 
2096          self.assertEqual( 
2097              [a], 
2098              list(d.iterancestors(tag='a'))) 
2099   
2100          self.assertEqual( 
2101              [b, a], 
2102              list(d.iterancestors('*'))) 
2103          self.assertEqual( 
2104              [b, a], 
2105              list(d.iterancestors(tag='*'))) 
2106   
2108          Element    = self.etree.Element 
2109          SubElement = self.etree.SubElement 
2110   
2111          a = Element('a') 
2112          b = SubElement(a, 'b') 
2113          c = SubElement(a, 'c') 
2114          d = SubElement(b, 'd') 
2115          self.assertEqual( 
2116              [b, a], 
2117              list(d.iterancestors(tag=('a', 'b')))) 
2118          self.assertEqual( 
2119              [b, a], 
2120              list(d.iterancestors('a', 'b'))) 
2121   
2122          self.assertEqual( 
2123              [], 
2124              list(d.iterancestors(tag=('w', 'x', 'y', 'z')))) 
2125          self.assertEqual( 
2126              [], 
2127              list(d.iterancestors('w', 'x', 'y', 'z'))) 
2128   
2129          self.assertEqual( 
2130              [], 
2131              list(d.iterancestors(tag=('d', 'x')))) 
2132          self.assertEqual( 
2133              [], 
2134              list(d.iterancestors('d', 'x'))) 
2135   
2136          self.assertEqual( 
2137              [b, a], 
2138              list(d.iterancestors(tag=('b', '*')))) 
2139          self.assertEqual( 
2140              [b, a], 
2141              list(d.iterancestors('b', '*'))) 
2142   
2143          self.assertEqual( 
2144              [b], 
2145              list(d.iterancestors(tag=('b', 'c')))) 
2146          self.assertEqual( 
2147              [b], 
2148              list(d.iterancestors('b', 'c'))) 
2149   
2151          Element = self.etree.Element 
2152          SubElement = self.etree.SubElement 
2153   
2154          a = Element('a') 
2155          b = SubElement(a, 'b') 
2156          c = SubElement(a, 'c') 
2157          d = SubElement(b, 'd') 
2158          e = SubElement(c, 'e') 
2159   
2160          self.assertEqual( 
2161              [b, d, c, e], 
2162              list(a.iterdescendants())) 
2163          self.assertEqual( 
2164              [], 
2165              list(d.iterdescendants())) 
2166   
2168          Element = self.etree.Element 
2169          SubElement = self.etree.SubElement 
2170   
2171          a = Element('a') 
2172          b = SubElement(a, 'b') 
2173          c = SubElement(a, 'c') 
2174          d = SubElement(b, 'd') 
2175          e = SubElement(c, 'e') 
2176   
2177          self.assertEqual( 
2178              [], 
2179              list(a.iterdescendants('a'))) 
2180          self.assertEqual( 
2181              [], 
2182              list(a.iterdescendants(tag='a'))) 
2183   
2184          a2 = SubElement(e, 'a') 
2185          self.assertEqual( 
2186              [a2], 
2187              list(a.iterdescendants('a'))) 
2188   
2189          self.assertEqual( 
2190              [a2], 
2191              list(c.iterdescendants('a'))) 
2192          self.assertEqual( 
2193              [a2], 
2194              list(c.iterdescendants(tag='a'))) 
2195   
2197          Element = self.etree.Element 
2198          SubElement = self.etree.SubElement 
2199   
2200          a = Element('a') 
2201          b = SubElement(a, 'b') 
2202          c = SubElement(a, 'c') 
2203          d = SubElement(b, 'd') 
2204          e = SubElement(c, 'e') 
2205   
2206          self.assertEqual( 
2207              [b, e], 
2208              list(a.iterdescendants(tag=('a', 'b', 'e')))) 
2209          self.assertEqual( 
2210              [b, e], 
2211              list(a.iterdescendants('a', 'b', 'e'))) 
2212   
2213          a2 = SubElement(e, 'a') 
2214          self.assertEqual( 
2215              [b, a2], 
2216              list(a.iterdescendants(tag=('a', 'b')))) 
2217          self.assertEqual( 
2218              [b, a2], 
2219              list(a.iterdescendants('a', 'b'))) 
2220   
2221          self.assertEqual( 
2222              [], 
2223              list(c.iterdescendants(tag=('x', 'y', 'z')))) 
2224          self.assertEqual( 
2225              [], 
2226              list(c.iterdescendants('x', 'y', 'z'))) 
2227   
2228          self.assertEqual( 
2229              [b, d, c, e, a2], 
2230              list(a.iterdescendants(tag=('x', 'y', 'z', '*')))) 
2231          self.assertEqual( 
2232              [b, d, c, e, a2], 
2233              list(a.iterdescendants('x', 'y', 'z', '*'))) 
2234   
2236          Element = self.etree.Element 
2237          SubElement = self.etree.SubElement 
2238   
2239          a = Element('a') 
2240          b = SubElement(a, 'b') 
2241          c = SubElement(a, 'c') 
2242          d = SubElement(b, 'd') 
2243          self.assertEqual( 
2244              a, 
2245              a.getroottree().getroot()) 
2246          self.assertEqual( 
2247              a, 
2248              b.getroottree().getroot()) 
2249          self.assertEqual( 
2250              a, 
2251              d.getroottree().getroot()) 
2252   
2254          Element    = self.etree.Element 
2255          SubElement = self.etree.SubElement 
2256   
2257          a = Element('a') 
2258          b = SubElement(a, 'b') 
2259          c = SubElement(a, 'c') 
2260          self.assertEqual( 
2261              None, 
2262              a.getnext()) 
2263          self.assertEqual( 
2264              c, 
2265              b.getnext()) 
2266          self.assertEqual( 
2267              None, 
2268              c.getnext()) 
2269   
2271          Element    = self.etree.Element 
2272          SubElement = self.etree.SubElement 
2273   
2274          a = Element('a') 
2275          b = SubElement(a, 'b') 
2276          c = SubElement(a, 'c') 
2277          d = SubElement(b, 'd') 
2278          self.assertEqual( 
2279              None, 
2280              a.getprevious()) 
2281          self.assertEqual( 
2282              b, 
2283              c.getprevious()) 
2284          self.assertEqual( 
2285              None, 
2286              b.getprevious()) 
2287   
2289          Element    = self.etree.Element 
2290          SubElement = self.etree.SubElement 
2291   
2292          a = Element('a') 
2293          b = SubElement(a, 'b') 
2294          c = SubElement(a, 'c') 
2295          d = SubElement(b, 'd') 
2296          self.assertEqual( 
2297              [], 
2298              list(a.itersiblings())) 
2299          self.assertEqual( 
2300              [c], 
2301              list(b.itersiblings())) 
2302          self.assertEqual( 
2303              [], 
2304              list(c.itersiblings())) 
2305          self.assertEqual( 
2306              [b], 
2307              list(c.itersiblings(preceding=True))) 
2308          self.assertEqual( 
2309              [], 
2310              list(b.itersiblings(preceding=True))) 
2311   
2313          Element    = self.etree.Element 
2314          SubElement = self.etree.SubElement 
2315   
2316          a = Element('a') 
2317          b = SubElement(a, 'b') 
2318          c = SubElement(a, 'c') 
2319          d = SubElement(b, 'd') 
2320          self.assertEqual( 
2321              [], 
2322              list(a.itersiblings(tag='XXX'))) 
2323          self.assertEqual( 
2324              [c], 
2325              list(b.itersiblings(tag='c'))) 
2326          self.assertEqual( 
2327              [c], 
2328              list(b.itersiblings(tag='*'))) 
2329          self.assertEqual( 
2330              [b], 
2331              list(c.itersiblings(preceding=True, tag='b'))) 
2332          self.assertEqual( 
2333              [], 
2334              list(c.itersiblings(preceding=True, tag='c'))) 
2335   
2337          Element    = self.etree.Element 
2338          SubElement = self.etree.SubElement 
2339   
2340          a = Element('a') 
2341          b = SubElement(a, 'b') 
2342          c = SubElement(a, 'c') 
2343          d = SubElement(b, 'd') 
2344          e = SubElement(a, 'e') 
2345          self.assertEqual( 
2346              [], 
2347              list(a.itersiblings(tag=('XXX', 'YYY')))) 
2348          self.assertEqual( 
2349              [c, e], 
2350              list(b.itersiblings(tag=('c', 'd', 'e')))) 
2351          self.assertEqual( 
2352              [b], 
2353              list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd')))) 
2354          self.assertEqual( 
2355              [c, b], 
2356              list(e.itersiblings(preceding=True, tag=('c', '*')))) 
2357   
2359          parseid = self.etree.parseid 
2360          XML     = self.etree.XML 
2361          xml_text = _bytes(''' 
2362          <!DOCTYPE document [ 
2363          <!ELEMENT document (h1,p)*> 
2364          <!ELEMENT h1 (#PCDATA)> 
2365          <!ATTLIST h1 myid ID #REQUIRED> 
2366          <!ELEMENT p  (#PCDATA)> 
2367          <!ATTLIST p  someid ID #REQUIRED> 
2368          ]> 
2369          <document> 
2370            <h1 myid="chapter1">...</h1> 
2371            <p id="note1" class="note">...</p> 
2372            <p>Regular paragraph.</p> 
2373            <p xml:id="xmlid">XML:ID paragraph.</p> 
2374            <p someid="warn1" class="warning">...</p> 
2375          </document> 
2376          ''') 
2377   
2378          tree, dic = parseid(BytesIO(xml_text)) 
2379          root = tree.getroot() 
2380          root2 = XML(xml_text) 
2381          self.assertEqual(self._writeElement(root), 
2382                            self._writeElement(root2)) 
2383          expected = { 
2384              "chapter1" : root[0], 
2385              "xmlid"    : root[3], 
2386              "warn1"    : root[4] 
2387              } 
2388          self.assertTrue("chapter1" in dic) 
2389          self.assertTrue("warn1" in dic) 
2390          self.assertTrue("xmlid" in dic) 
2391          self._checkIDDict(dic, expected) 
2392   
2394          XMLDTDID = self.etree.XMLDTDID 
2395          XML      = self.etree.XML 
2396          xml_text = _bytes(''' 
2397          <!DOCTYPE document [ 
2398          <!ELEMENT document (h1,p)*> 
2399          <!ELEMENT h1 (#PCDATA)> 
2400          <!ATTLIST h1 myid ID #REQUIRED> 
2401          <!ELEMENT p  (#PCDATA)> 
2402          <!ATTLIST p  someid ID #REQUIRED> 
2403          ]> 
2404          <document> 
2405            <h1 myid="chapter1">...</h1> 
2406            <p id="note1" class="note">...</p> 
2407            <p>Regular paragraph.</p> 
2408            <p xml:id="xmlid">XML:ID paragraph.</p> 
2409            <p someid="warn1" class="warning">...</p> 
2410          </document> 
2411          ''') 
2412   
2413          root, dic = XMLDTDID(xml_text) 
2414          root2 = XML(xml_text) 
2415          self.assertEqual(self._writeElement(root), 
2416                            self._writeElement(root2)) 
2417          expected = { 
2418              "chapter1" : root[0], 
2419              "xmlid"    : root[3], 
2420              "warn1"    : root[4] 
2421              } 
2422          self.assertTrue("chapter1" in dic) 
2423          self.assertTrue("warn1" in dic) 
2424          self.assertTrue("xmlid" in dic) 
2425          self._checkIDDict(dic, expected) 
2426   
2428          XMLDTDID = self.etree.XMLDTDID 
2429          XML      = self.etree.XML 
2430          xml_text = _bytes(''' 
2431          <document> 
2432            <h1 myid="chapter1">...</h1> 
2433            <p id="note1" class="note">...</p> 
2434            <p>Regular paragraph.</p> 
2435            <p someid="warn1" class="warning">...</p> 
2436          </document> 
2437          ''') 
2438   
2439          root, dic = XMLDTDID(xml_text) 
2440          root2 = XML(xml_text) 
2441          self.assertEqual(self._writeElement(root), 
2442                            self._writeElement(root2)) 
2443          expected = {} 
2444          self._checkIDDict(dic, expected) 
2445   
2447          XMLDTDID = self.etree.XMLDTDID 
2448          XML      = self.etree.XML 
2449          xml_text = _bytes(''' 
2450          <!DOCTYPE document [ 
2451          <!ELEMENT document (h1,p)*> 
2452          <!ELEMENT h1 (#PCDATA)> 
2453          <!ATTLIST h1 myid ID #REQUIRED> 
2454          <!ELEMENT p  (#PCDATA)> 
2455          <!ATTLIST p  someid ID #REQUIRED> 
2456          ]> 
2457          <document> 
2458            <h1 myid="chapter1">...</h1> 
2459            <p id="note1" class="note">...</p> 
2460            <p>Regular paragraph.</p> 
2461            <p xml:id="xmlid">XML:ID paragraph.</p> 
2462            <p someid="warn1" class="warning">...</p> 
2463          </document> 
2464          ''') 
2465   
2466          parser = etree.XMLParser(collect_ids=False) 
2467          root, dic = XMLDTDID(xml_text, parser=parser) 
2468          root2 = XML(xml_text) 
2469          self.assertEqual(self._writeElement(root), 
2470                           self._writeElement(root2)) 
2471          self.assertFalse(dic) 
2472          self._checkIDDict(dic, {}) 
2473   
2475          self.assertEqual(len(dic), 
2476                            len(expected)) 
2477          self.assertEqual(sorted(dic.items()), 
2478                            sorted(expected.items())) 
2479          if sys.version_info < (3,): 
2480              self.assertEqual(sorted(dic.iteritems()), 
2481                                sorted(expected.iteritems())) 
2482          self.assertEqual(sorted(dic.keys()), 
2483                            sorted(expected.keys())) 
2484          if sys.version_info < (3,): 
2485              self.assertEqual(sorted(dic.iterkeys()), 
2486                                sorted(expected.iterkeys())) 
2487          if sys.version_info < (3,): 
2488              self.assertEqual(sorted(dic.values()), 
2489                                sorted(expected.values())) 
2490              self.assertEqual(sorted(dic.itervalues()), 
2491                                sorted(expected.itervalues())) 
2492   
2494          etree = self.etree 
2495   
2496          r = {'foo': 'http://ns.infrae.com/foo'} 
2497          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2498          self.assertEqual( 
2499              'foo', 
2500              e.prefix) 
2501          self.assertEqual( 
2502              _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'), 
2503              self._writeElement(e)) 
2504           
2506          etree = self.etree 
2507   
2508          r = {None: 'http://ns.infrae.com/foo'} 
2509          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2510          self.assertEqual( 
2511              None, 
2512              e.prefix) 
2513          self.assertEqual( 
2514              '{http://ns.infrae.com/foo}bar', 
2515              e.tag) 
2516          self.assertEqual( 
2517              _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'), 
2518              self._writeElement(e)) 
2519   
2521          etree = self.etree 
2522   
2523          r = {None: 'http://ns.infrae.com/foo', 'p': 'http://test/'} 
2524          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2525          self.assertEqual(None, e.prefix) 
2526          self.assertEqual('{http://ns.infrae.com/foo}bar', e.tag) 
2527          self.assertEqual( 
2528              _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:p="http://test/"></bar>'), 
2529              self._writeElement(e)) 
2530   
2532          etree = self.etree 
2533   
2534          r = {None: 'http://ns.infrae.com/foo', 
2535               'hoi': 'http://ns.infrae.com/hoi'} 
2536          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2537          e.set('{http://ns.infrae.com/hoi}test', 'value') 
2538          self.assertEqual( 
2539              _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'), 
2540              self._writeElement(e)) 
2541   
2543          etree = self.etree 
2544   
2545          root = etree.Element('{http://test/ns}root', 
2546                               nsmap={None: 'http://test/ns'}) 
2547          sub = etree.Element('{http://test/ns}sub', 
2548                              nsmap={'test': 'http://test/ns'}) 
2549   
2550          sub.attrib['{http://test/ns}attr'] = 'value' 
2551          self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 
2552          self.assertEqual( 
2553              _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 
2554              etree.tostring(sub)) 
2555   
2556          root.append(sub) 
2557          self.assertEqual( 
2558              _bytes('<root xmlns="http://test/ns">' 
2559                     '<sub xmlns:test="http://test/ns" test:attr="value"/>' 
2560                     '</root>'), 
2561              etree.tostring(root)) 
2562   
2564          etree = self.etree 
2565   
2566          root = etree.Element('root') 
2567          sub = etree.Element('{http://test/ns}sub', 
2568                              nsmap={'test': 'http://test/ns'}) 
2569   
2570          sub.attrib['{http://test/ns}attr'] = 'value' 
2571          self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 
2572          self.assertEqual( 
2573              _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 
2574              etree.tostring(sub)) 
2575   
2576          root.append(sub) 
2577          self.assertEqual( 
2578              _bytes('<root>' 
2579                     '<test:sub xmlns:test="http://test/ns" test:attr="value"/>' 
2580                     '</root>'), 
2581              etree.tostring(root)) 
2582   
2584          etree = self.etree 
2585   
2586          root = etree.Element('root') 
2587          sub = etree.Element('{http://test/ns}sub', 
2588                              nsmap={None: 'http://test/ns'}) 
2589   
2590          sub.attrib['{http://test/ns}attr'] = 'value' 
2591          self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 
2592          self.assertEqual( 
2593              _bytes('<sub xmlns="http://test/ns" ' 
2594                     'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 
2595              etree.tostring(sub)) 
2596   
2597          root.append(sub) 
2598          self.assertEqual( 
2599              _bytes('<root>' 
2600                     '<sub xmlns="http://test/ns"' 
2601                     ' xmlns:ns0="http://test/ns" ns0:attr="value"/>' 
2602                     '</root>'), 
2603              etree.tostring(root)) 
2604   
2606          etree = self.etree 
2607   
2608          root = etree.Element('{http://test/ns}root', 
2609                               nsmap={'test': 'http://test/ns', 
2610                                      None: 'http://test/ns'}) 
2611          sub = etree.Element('{http://test/ns}sub', 
2612                              nsmap={None: 'http://test/ns'}) 
2613   
2614          sub.attrib['{http://test/ns}attr'] = 'value' 
2615          self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 
2616          self.assertEqual( 
2617              _bytes('<sub xmlns="http://test/ns" ' 
2618                     'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 
2619              etree.tostring(sub)) 
2620   
2621          root.append(sub) 
2622          self.assertEqual( 
2623              _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">' 
2624                     '<test:sub test:attr="value"/>' 
2625                     '</test:root>'), 
2626              etree.tostring(root)) 
2627   
2629          etree = self.etree 
2630          r = {None: 'http://ns.infrae.com/foo', 
2631               'hoi': 'http://ns.infrae.com/hoi'}  
2632          e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 
2633          tree = etree.ElementTree(element=e) 
2634          etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 
2635          self.assertEqual( 
2636              _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'), 
2637              self._writeElement(e)) 
2638   
2640          etree = self.etree 
2641   
2642          r = {None: 'http://ns.infrae.com/foo'} 
2643          e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2644          e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2645   
2646          e1.append(e2) 
2647   
2648          self.assertEqual( 
2649              None, 
2650              e1.prefix) 
2651          self.assertEqual( 
2652              None, 
2653              e1[0].prefix) 
2654          self.assertEqual( 
2655              '{http://ns.infrae.com/foo}bar', 
2656              e1.tag) 
2657          self.assertEqual( 
2658              '{http://ns.infrae.com/foo}bar', 
2659              e1[0].tag) 
2660   
2662          etree = self.etree 
2663   
2664          r = {None: 'http://ns.infrae.com/BAR'} 
2665          e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 
2666          e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2667   
2668          e1.append(e2) 
2669   
2670          self.assertEqual( 
2671              None, 
2672              e1.prefix) 
2673          self.assertNotEqual( 
2674              None, 
2675              e2.prefix) 
2676          self.assertEqual( 
2677              '{http://ns.infrae.com/BAR}bar', 
2678              e1.tag) 
2679          self.assertEqual( 
2680              '{http://ns.infrae.com/foo}bar', 
2681              e2.tag) 
2682   
2684          ns_href = "http://a.b.c" 
2685          one = self.etree.fromstring( 
2686              _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 
2687          baz = one[0][0] 
2688   
2689          two = self.etree.fromstring( 
2690              _bytes('<root xmlns:ns="%s"/>' % ns_href)) 
2691          two.append(baz) 
2692          del one # make sure the source document is deallocated 
2693   
2694          self.assertEqual('{%s}baz' % ns_href, baz.tag) 
2695          self.assertEqual( 
2696              _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href), 
2697              self.etree.tostring(two)) 
2698   
2700          xml = _bytes( 
2701              '<foo xmlns="F" xmlns:x="x">' 
2702              '<bar xmlns:ns="NS" xmlns:b="b" xmlns="B">' 
2703              '<ns:baz/>' 
2704              '</bar></foo>' 
2705          ) 
2706          root = self.etree.fromstring(xml) 
2707          self.assertEqual(xml, self.etree.tostring(root)) 
2708          self.etree.cleanup_namespaces(root) 
2709          self.assertEqual( 
2710              _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'), 
2711              self.etree.tostring(root)) 
2712   
2714          xml = _bytes( 
2715              '<foo xmlns="F" xmlns:x="X" xmlns:a="A">' 
2716              '<bar xmlns:ns="NS" xmlns:b="b" xmlns="B">' 
2717              '<ns:baz a:test="attr"/>' 
2718              '</bar></foo>' 
2719          ) 
2720          root = self.etree.fromstring(xml) 
2721          self.assertEqual(xml, self.etree.tostring(root)) 
2722          self.etree.cleanup_namespaces(root) 
2723          self.assertEqual( 
2724              _bytes('<foo xmlns="F" xmlns:a="A">' 
2725                     '<bar xmlns:ns="NS" xmlns="B">' 
2726                     '<ns:baz a:test="attr"/>' 
2727                     '</bar></foo>'), 
2728              self.etree.tostring(root)) 
2729   
2731          xml = ('<n12:foo ' + 
2732                 ' '.join('xmlns:n{n}="NS{n}"'.format(n=i) for i in range(100)) + 
2733                 '><n68:a/></n12:foo>').encode('utf8') 
2734          root = self.etree.fromstring(xml) 
2735          self.assertEqual(xml, self.etree.tostring(root)) 
2736          self.etree.cleanup_namespaces(root) 
2737          self.assertEqual( 
2738              b'<n12:foo xmlns:n12="NS12" xmlns:n68="NS68"><n68:a/></n12:foo>', 
2739              self.etree.tostring(root)) 
2740   
2742          xml = ('<root>' + 
2743                 ''.join('<a xmlns:n{n}="NS{n}">'.format(n=i) for i in range(100)) + 
2744                 '<n64:x/>' + '</a>'*100 + '</root>').encode('utf8') 
2745          root = self.etree.fromstring(xml) 
2746          self.assertEqual(xml, self.etree.tostring(root)) 
2747          self.etree.cleanup_namespaces(root) 
2748          self.assertEqual( 
2749              b'<root>' + b'<a>'*64 + b'<a xmlns:n64="NS64">' + b'<a>'*35 + 
2750              b'<n64:x/>' + b'</a>'*100 + b'</root>', 
2751              self.etree.tostring(root)) 
2752   
2754          xml = ('<root>' + 
2755                 ''.join('<a xmlns:n{n}="NS{n}">'.format(n=i) for i in range(100)) + 
2756                 '<n64:x xmlns:a="A" a:attr="X"/>' + 
2757                 '</a>'*100 + 
2758                 '</root>').encode('utf8') 
2759          root = self.etree.fromstring(xml) 
2760          self.assertEqual(xml, self.etree.tostring(root)) 
2761          self.etree.cleanup_namespaces(root, top_nsmap={'n64': 'NS64'}) 
2762          self.assertEqual( 
2763              b'<root xmlns:n64="NS64">' + b'<a>'*100 + 
2764              b'<n64:x xmlns:a="A" a:attr="X"/>' + b'</a>'*100 + b'</root>', 
2765              self.etree.tostring(root)) 
2766   
2768          xml = ('<root xmlns:n64="NS64" xmlns:foo="FOO" xmlns:unused1="UNUSED" xmlns:no="NO">' 
2769                 '<a xmlns:unused2="UNUSED"><n64:x xmlns:a="A" a:attr="X"/></a>' 
2770                 '<foo>foo:bar</foo>' 
2771                 '</root>').encode('utf8') 
2772          root = self.etree.fromstring(xml) 
2773          self.assertEqual(xml, self.etree.tostring(root)) 
2774          self.etree.cleanup_namespaces(root, keep_ns_prefixes=['foo']) 
2775          self.assertEqual( 
2776              b'<root xmlns:n64="NS64" xmlns:foo="FOO">' 
2777              b'<a><n64:x xmlns:a="A" a:attr="X"/></a>' 
2778              b'<foo>foo:bar</foo>' 
2779              b'</root>', 
2780              self.etree.tostring(root)) 
2781   
2783          xml = ('<root xmlns:n64="NS64" xmlns:unused1="UNUSED" xmlns:no="NO">' 
2784                 '<sub xmlns:foo="FOO">' 
2785                 '<a xmlns:unused2="UNUSED"><n64:x xmlns:a="A" a:attr="X"/></a>' 
2786                 '<foo>foo:bar</foo>' 
2787                 '</sub>' 
2788                 '</root>').encode('utf8') 
2789          root = self.etree.fromstring(xml) 
2790          self.assertEqual(xml, self.etree.tostring(root)) 
2791          self.etree.cleanup_namespaces( 
2792              root, 
2793              top_nsmap={'foo': 'FOO', 'unused1': 'UNUSED'}, 
2794              keep_ns_prefixes=['foo']) 
2795          self.assertEqual( 
2796              b'<root xmlns:n64="NS64" xmlns:foo="FOO">' 
2797              b'<sub>' 
2798              b'<a><n64:x xmlns:a="A" a:attr="X"/></a>' 
2799              b'<foo>foo:bar</foo>' 
2800              b'</sub>' 
2801              b'</root>', 
2802              self.etree.tostring(root)) 
2803   
2805          etree = self.etree 
2806   
2807          r = {None: 'http://ns.infrae.com/foo', 
2808               'hoi': 'http://ns.infrae.com/hoi'} 
2809          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2810          self.assertEqual( 
2811              r, 
2812              e.nsmap) 
2813   
2815          etree = self.etree 
2816   
2817          re = {None: 'http://ns.infrae.com/foo', 
2818               'hoi': 'http://ns.infrae.com/hoi'} 
2819          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re) 
2820   
2821          rs = {None: 'http://ns.infrae.com/honk', 
2822               'top': 'http://ns.infrae.com/top'} 
2823          s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs) 
2824   
2825          r = re.copy() 
2826          r.update(rs) 
2827          self.assertEqual(re, e.nsmap) 
2828          self.assertEqual(r,  s.nsmap) 
2829   
2831          etree = self.etree 
2832          el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description') 
2833          self.assertEqual({'hha': None}, el.nsmap) 
2834   
2836          Element = self.etree.Element 
2837          SubElement = self.etree.SubElement 
2838   
2839          a = Element('a') 
2840          b = SubElement(a, 'b') 
2841          c = SubElement(a, 'c') 
2842          d = SubElement(b, 'd') 
2843          e = SubElement(c, 'e') 
2844          f = SubElement(c, 'f') 
2845   
2846          self.assertEqual( 
2847              [a, b], 
2848                 list(a.getiterator('a', 'b'))) 
2849          self.assertEqual( 
2850              [], 
2851                list(a.getiterator('x', 'y'))) 
2852          self.assertEqual( 
2853              [a, f], 
2854                list(a.getiterator('f', 'a'))) 
2855          self.assertEqual( 
2856              [c, e, f], 
2857                 list(c.getiterator('c', '*', 'a'))) 
2858          self.assertEqual( 
2859              [], 
2860                    list(a.getiterator( (), () ))) 
2861   
2863          Element = self.etree.Element 
2864          SubElement = self.etree.SubElement 
2865   
2866          a = Element('a') 
2867          b = SubElement(a, 'b') 
2868          c = SubElement(a, 'c') 
2869          d = SubElement(b, 'd') 
2870          e = SubElement(c, 'e') 
2871          f = SubElement(c, 'f') 
2872   
2873          self.assertEqual( 
2874              [a, b], 
2875                    list(a.getiterator( ('a', 'b') ))) 
2876          self.assertEqual( 
2877              [], 
2878                list(a.getiterator( ('x', 'y') ))) 
2879          self.assertEqual( 
2880              [a, f], 
2881                    list(a.getiterator( ('f', 'a') ))) 
2882          self.assertEqual( 
2883              [c, e, f], 
2884                       list(c.getiterator( ('c', '*', 'a') ))) 
2885          self.assertEqual( 
2886              [], 
2887                list(a.getiterator( () ))) 
2888   
2890          Element = self.etree.Element 
2891          SubElement = self.etree.SubElement 
2892   
2893          a = Element('{a}a') 
2894          b = SubElement(a, '{a}b') 
2895          c = SubElement(a, '{a}c') 
2896          d = SubElement(b, '{b}d') 
2897          e = SubElement(c, '{a}e') 
2898          f = SubElement(c, '{b}f') 
2899          g = SubElement(c, 'g') 
2900   
2901          self.assertEqual( 
2902              [a], 
2903              list(a.getiterator('{a}a'))) 
2904          self.assertEqual( 
2905              [], 
2906              list(a.getiterator('{b}a'))) 
2907          self.assertEqual( 
2908              [], 
2909              list(a.getiterator('a'))) 
2910          self.assertEqual( 
2911              [a,b,d,c,e,f,g], 
2912              list(a.getiterator('*'))) 
2913          self.assertEqual( 
2914              [f], 
2915              list(c.getiterator('{b}*'))) 
2916          self.assertEqual( 
2917              [d, f], 
2918              list(a.getiterator('{b}*'))) 
2919          self.assertEqual( 
2920              [g], 
2921              list(a.getiterator('g'))) 
2922          self.assertEqual( 
2923              [g], 
2924              list(a.getiterator('{}g'))) 
2925          self.assertEqual( 
2926              [g], 
2927              list(a.getiterator('{}*'))) 
2928   
2930          Element = self.etree.Element 
2931          SubElement = self.etree.SubElement 
2932   
2933          a = Element('{a}a') 
2934          b = SubElement(a, '{nsA}b') 
2935          c = SubElement(b, '{nsB}b') 
2936          d = SubElement(a, 'b') 
2937          e = SubElement(a, '{nsA}e') 
2938          f = SubElement(e, '{nsB}e') 
2939          g = SubElement(e, 'e') 
2940   
2941          self.assertEqual( 
2942              [b, c, d], 
2943              list(a.getiterator('{*}b'))) 
2944          self.assertEqual( 
2945              [e, f, g], 
2946              list(a.getiterator('{*}e'))) 
2947          self.assertEqual( 
2948              [a, b, c, d, e, f, g], 
2949              list(a.getiterator('{*}*'))) 
2950   
2952          Element = self.etree.Element 
2953          Entity = self.etree.Entity 
2954          SubElement = self.etree.SubElement 
2955   
2956          a = Element('a') 
2957          b = SubElement(a, 'b') 
2958          entity_b = Entity("TEST-b") 
2959          b.append(entity_b) 
2960   
2961          self.assertEqual( 
2962              [entity_b], 
2963              list(a.getiterator(Entity))) 
2964   
2965          entity_a = Entity("TEST-a") 
2966          a.append(entity_a) 
2967   
2968          self.assertEqual( 
2969              [entity_b, entity_a], 
2970              list(a.getiterator(Entity))) 
2971   
2972          self.assertEqual( 
2973              [entity_b], 
2974              list(b.getiterator(Entity))) 
2975   
2977          Element = self.etree.Element 
2978          Comment = self.etree.Comment 
2979          PI = self.etree.PI 
2980          SubElement = self.etree.SubElement 
2981   
2982          a = Element('a') 
2983          b = SubElement(a, 'b') 
2984          a.append(Comment("test")) 
2985          a.append(PI("pi", "content")) 
2986          c = SubElement(a, 'c') 
2987   
2988          self.assertEqual( 
2989              [a, b, c], 
2990              list(a.getiterator(Element))) 
2991   
2993          # ElementTree iterates over everything here 
2994          Element = self.etree.Element 
2995          Comment = self.etree.Comment 
2996          PI = self.etree.PI 
2997          SubElement = self.etree.SubElement 
2998   
2999          a = Element('a') 
3000          b = SubElement(a, 'b') 
3001          a.append(Comment("test")) 
3002          a.append(PI("pi", "content")) 
3003          c = SubElement(a, 'c') 
3004   
3005          self.assertEqual( 
3006              [a, b, c], 
3007              list(a.getiterator('*'))) 
3008   
3010          a  = etree.Element("a") 
3011          b  = etree.SubElement(a, "b") 
3012          c  = etree.SubElement(a, "c") 
3013          d1 = etree.SubElement(c, "d") 
3014          d2 = etree.SubElement(c, "d") 
3015          c.text = d1.text = 'TEXT' 
3016   
3017          tree = etree.ElementTree(a) 
3018          self.assertEqual('.', tree.getelementpath(a)) 
3019          self.assertEqual('c/d[1]', tree.getelementpath(d1)) 
3020          self.assertEqual('c/d[2]', tree.getelementpath(d2)) 
3021   
3022          self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 
3023          self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 
3024   
3025          tree = etree.ElementTree(c) 
3026          self.assertEqual('.', tree.getelementpath(c)) 
3027          self.assertEqual('d[2]', tree.getelementpath(d2)) 
3028          self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 
3029   
3030          tree = etree.ElementTree(b)  # not a parent of a/c/d1/d2 
3031          self.assertEqual('.', tree.getelementpath(b)) 
3032          self.assertRaises(ValueError, tree.getelementpath, a) 
3033          self.assertRaises(ValueError, tree.getelementpath, c) 
3034          self.assertRaises(ValueError, tree.getelementpath, d2) 
3035   
3037          a  = etree.Element("{http://ns1/}a") 
3038          b  = etree.SubElement(a, "{http://ns1/}b") 
3039          c  = etree.SubElement(a, "{http://ns1/}c") 
3040          d1 = etree.SubElement(c, "{http://ns1/}d") 
3041          d2 = etree.SubElement(c, "{http://ns2/}d") 
3042          d3 = etree.SubElement(c, "{http://ns1/}d") 
3043   
3044          tree = etree.ElementTree(a) 
3045          self.assertEqual('.', tree.getelementpath(a)) 
3046          self.assertEqual('{http://ns1/}c/{http://ns1/}d[1]', 
3047                           tree.getelementpath(d1)) 
3048          self.assertEqual('{http://ns1/}c/{http://ns2/}d', 
3049                           tree.getelementpath(d2)) 
3050          self.assertEqual('{http://ns1/}c/{http://ns1/}d[2]', 
3051                           tree.getelementpath(d3)) 
3052   
3053          self.assertEqual(a, tree.find(tree.getelementpath(a))) 
3054          self.assertEqual(b, tree.find(tree.getelementpath(b))) 
3055          self.assertEqual(c, tree.find(tree.getelementpath(c))) 
3056          self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 
3057          self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 
3058          self.assertEqual(d3, tree.find(tree.getelementpath(d3))) 
3059   
3060          tree = etree.ElementTree(c) 
3061          self.assertEqual('{http://ns1/}d[1]', tree.getelementpath(d1)) 
3062          self.assertEqual('{http://ns2/}d', tree.getelementpath(d2)) 
3063          self.assertEqual('{http://ns1/}d[2]', tree.getelementpath(d3)) 
3064          self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 
3065          self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 
3066          self.assertEqual(d3, tree.find(tree.getelementpath(d3))) 
3067   
3068          tree = etree.ElementTree(b)  # not a parent of d1/d2 
3069          self.assertRaises(ValueError, tree.getelementpath, d1) 
3070          self.assertRaises(ValueError, tree.getelementpath, d2) 
3071   
3073          XML = self.etree.XML 
3074          ElementTree = self.etree.ElementTree 
3075          QName = self.etree.QName 
3076          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 
3077          self.assertEqual(tree.find(QName("c")), tree.getroot()[2]) 
3078   
3080          XML = self.etree.XML 
3081          ElementTree = self.etree.ElementTree 
3082          QName = self.etree.QName 
3083          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 
3084          self.assertEqual(len(list(tree.findall(QName("c")))), 1) 
3085   
3087          XML = self.etree.XML 
3088          ElementTree = self.etree.ElementTree 
3089          QName = self.etree.QName 
3090          tree = ElementTree(XML( 
3091                  _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))) 
3092          self.assertEqual(len(list(tree.findall(QName("b")))), 2) 
3093          self.assertEqual(len(list(tree.findall(QName("X", "b")))), 1) 
3094   
3096          XML = self.etree.XML 
3097          root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')) 
3098          self.assertEqual(len(root.findall(".//{X}b")), 2) 
3099          self.assertEqual(len(root.findall(".//{X}*")), 2) 
3100          self.assertEqual(len(root.findall(".//b")), 3) 
3101   
3103          XML = self.etree.XML 
3104          root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>')) 
3105          nsmap = {'xx': 'X'} 
3106          self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) 
3107          self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2) 
3108          self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2) 
3109          nsmap = {'xx': 'Y'} 
3110          self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1) 
3111          self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1) 
3112          self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2) 
3113   
3115          XML = self.etree.XML 
3116          root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>')) 
3117          nsmap = {'xx': 'X'} 
3118          self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) 
3119          nsmap = {'xx': 'X', None: 'Y'} 
3120          self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 1) 
3121          nsmap = {'xx': 'X', '': 'Y'} 
3122          self.assertRaises(ValueError, root.findall, ".//xx:b", namespaces=nsmap) 
3123   
3125          XML = self.etree.XML 
3126          root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>')) 
3127          self.assertRaises(SyntaxError, root.findall, '') 
3128          self.assertRaises(SyntaxError, root.findall, '//')  # absolute path on Element 
3129          self.assertRaises(SyntaxError, root.findall, './//') 
3130   
3132          etree = self.etree 
3133          e = etree.Element('foo') 
3134          for i in range(10): 
3135              etree.SubElement(e, 'a%s' % i) 
3136          for i in range(10): 
3137              self.assertEqual( 
3138                  i, 
3139                  e.index(e[i])) 
3140          self.assertEqual( 
3141              3, e.index(e[3], 3)) 
3142          self.assertRaises( 
3143              ValueError, e.index, e[3], 4) 
3144          self.assertRaises( 
3145              ValueError, e.index, e[3], 0, 2) 
3146          self.assertRaises( 
3147              ValueError, e.index, e[8], 0, -3) 
3148          self.assertRaises( 
3149              ValueError, e.index, e[8], -5, -3) 
3150          self.assertEqual( 
3151              8, e.index(e[8], 0, -1)) 
3152          self.assertEqual( 
3153              8, e.index(e[8], -12, -1)) 
3154          self.assertEqual( 
3155              0, e.index(e[0], -12, -1)) 
3156   
3158          etree = self.etree 
3159          e = etree.Element('foo') 
3160          for i in range(10): 
3161              el = etree.SubElement(e, 'a%s' % i) 
3162              el.text = "text%d" % i 
3163              el.tail = "tail%d" % i 
3164   
3165          child0 = e[0] 
3166          child1 = e[1] 
3167          child2 = e[2] 
3168   
3169          e.replace(e[0], e[1]) 
3170          self.assertEqual( 
3171              9, len(e)) 
3172          self.assertEqual( 
3173              child1, e[0]) 
3174          self.assertEqual( 
3175              child1.text, "text1") 
3176          self.assertEqual( 
3177              child1.tail, "tail1") 
3178          self.assertEqual( 
3179              child0.tail, "tail0") 
3180          self.assertEqual( 
3181              child2, e[1]) 
3182   
3183          e.replace(e[-1], e[0]) 
3184          self.assertEqual( 
3185              child1, e[-1]) 
3186          self.assertEqual( 
3187              child1.text, "text1") 
3188          self.assertEqual( 
3189              child1.tail, "tail1") 
3190          self.assertEqual( 
3191              child2, e[0]) 
3192   
3194          etree = self.etree 
3195          e = etree.Element('foo') 
3196          for i in range(10): 
3197              etree.SubElement(e, 'a%s' % i) 
3198   
3199          new_element = etree.Element("test") 
3200          new_element.text = "TESTTEXT" 
3201          new_element.tail = "TESTTAIL" 
3202          child1 = e[1] 
3203          e.replace(e[0], new_element) 
3204          self.assertEqual( 
3205              new_element, e[0]) 
3206          self.assertEqual( 
3207              "TESTTEXT", 
3208              e[0].text) 
3209          self.assertEqual( 
3210              "TESTTAIL", 
3211              e[0].tail) 
3212          self.assertEqual( 
3213              child1, e[1]) 
3214   
3216          Element = self.etree.Element 
3217          SubElement = self.etree.SubElement 
3218   
3219          a = Element('a') 
3220   
3221          e = Element('e') 
3222          f = Element('f') 
3223          g = Element('g') 
3224   
3225          s = [e, f, g] 
3226          a[::-1] = s 
3227          self.assertEqual( 
3228              [g, f, e], 
3229              list(a)) 
3230   
3232          Element = self.etree.Element 
3233          SubElement = self.etree.SubElement 
3234   
3235          a = Element('a') 
3236          b = SubElement(a, 'b') 
3237          c = SubElement(a, 'c') 
3238          d = SubElement(a, 'd') 
3239          e = SubElement(a, 'e') 
3240   
3241          x = Element('x') 
3242          y = Element('y') 
3243   
3244          a[1::2] = [x, y] 
3245          self.assertEqual( 
3246              [b, x, d, y], 
3247              list(a)) 
3248   
3250          Element = self.etree.Element 
3251          SubElement = self.etree.SubElement 
3252   
3253          a = Element('a') 
3254          b = SubElement(a, 'b') 
3255          c = SubElement(a, 'c') 
3256          d = SubElement(a, 'd') 
3257          e = SubElement(a, 'e') 
3258   
3259          x = Element('x') 
3260          y = Element('y') 
3261   
3262          a[1::-1] = [x, y] 
3263          self.assertEqual( 
3264              [y, x, d, e], 
3265              list(a)) 
3266   
3268          Element = self.etree.Element 
3269          SubElement = self.etree.SubElement 
3270   
3271          a = Element('a') 
3272          b = SubElement(a, 'b') 
3273          c = SubElement(a, 'c') 
3274          d = SubElement(a, 'd') 
3275          e = SubElement(a, 'e') 
3276   
3277          x = Element('x') 
3278          y = Element('y') 
3279   
3280          a[::-2] = [x, y] 
3281          self.assertEqual( 
3282              [b, y, d, x], 
3283              list(a)) 
3284   
3286          Element = self.etree.Element 
3287          SubElement = self.etree.SubElement 
3288          try: 
3289              slice 
3290          except NameError: 
3291              print("slice() not found") 
3292              return 
3293   
3294          a = Element('a') 
3295          b = SubElement(a, 'b') 
3296          c = SubElement(a, 'c') 
3297          d = SubElement(a, 'd') 
3298          e = SubElement(a, 'e') 
3299   
3300          x = Element('x') 
3301          y = Element('y') 
3302          z = Element('z') 
3303   
3304          self.assertRaises( 
3305              ValueError, 
3306              operator.setitem, a, slice(1,None,2), [x, y, z]) 
3307   
3308          self.assertEqual( 
3309              [b, c, d, e], 
3310              list(a)) 
3311   
3313          XML = self.etree.XML 
3314          root = XML(_bytes('''<?xml version="1.0"?> 
3315          <root><test> 
3316   
3317          <bla/></test> 
3318          </root> 
3319          ''')) 
3320   
3321          self.assertEqual( 
3322              [2, 2, 4], 
3323              [ el.sourceline for el in root.getiterator() ]) 
3324   
3326          XML = self.etree.XML 
3327          root = XML(_bytes( 
3328              '<?xml version="1.0"?>\n' 
3329              '<root>' + '\n' * 65536 + 
3330              '<p>' + '\n' * 65536 + '</p>\n' + 
3331              '<br/>\n' 
3332              '</root>')) 
3333   
3334          if self.etree.LIBXML_VERSION >= (2, 9): 
3335              expected = [2, 131074, 131076] 
3336          else: 
3337              expected = [2, 65535, 65535] 
3338   
3339          self.assertEqual(expected, [el.sourceline for el in root.iter()]) 
3340   
3342          parse = self.etree.parse 
3343          tree = parse(fileInTestDir('include/test_xinclude.xml')) 
3344   
3345          self.assertEqual( 
3346              [1, 2, 3], 
3347              [ el.sourceline for el in tree.getiterator() ]) 
3348   
3350          iterparse = self.etree.iterparse 
3351          lines = [ el.sourceline for (event, el) in  
3352                    iterparse(fileInTestDir('include/test_xinclude.xml')) ] 
3353   
3354          self.assertEqual( 
3355              [2, 3, 1], 
3356              lines) 
3357   
3359          iterparse = self.etree.iterparse 
3360          lines = [ el.sourceline for (event, el) in  
3361                    iterparse(fileInTestDir('include/test_xinclude.xml'), 
3362                              events=("start",)) ] 
3363   
3364          self.assertEqual( 
3365              [1, 2, 3], 
3366              lines) 
3367   
3369          Element = self.etree.Element 
3370          SubElement = self.etree.SubElement 
3371          el = Element("test") 
3372          self.assertEqual(None, el.sourceline) 
3373   
3374          child = SubElement(el, "test") 
3375          self.assertEqual(None, el.sourceline) 
3376          self.assertEqual(None, child.sourceline) 
3377   
3379          etree = self.etree 
3380          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 
3381          docinfo = root.getroottree().docinfo 
3382          self.assertEqual(docinfo.URL, "http://no/such/url") 
3383   
3385          etree = self.etree 
3386          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 
3387          docinfo = root.getroottree().docinfo 
3388          self.assertEqual(docinfo.URL, "http://no/such/url") 
3389          docinfo.URL = "https://secret/url" 
3390          self.assertEqual(docinfo.URL, "https://secret/url") 
3391   
3393          etree = self.etree 
3394          tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url") 
3395          docinfo = tree.docinfo 
3396          self.assertEqual(docinfo.URL, "http://no/such/url") 
3397   
3399          etree = self.etree 
3400          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 
3401                             base_url="http://no/such/url") 
3402          docinfo = tree.docinfo 
3403          self.assertEqual(docinfo.URL, "http://no/such/url") 
3404   
3406          etree = self.etree 
3407          root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url") 
3408          docinfo = root.getroottree().docinfo 
3409          self.assertEqual(docinfo.URL, "http://no/such/url") 
3410   
3412          etree = self.etree 
3413          xml_header = '<?xml version="1.0" encoding="ascii"?>' 
3414          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 
3415          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 
3416          doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id) 
3417   
3418          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 
3419   
3420          tree = etree.parse(BytesIO(xml)) 
3421          docinfo = tree.docinfo 
3422          self.assertEqual(docinfo.encoding,    "ascii") 
3423          self.assertEqual(docinfo.xml_version, "1.0") 
3424          self.assertEqual(docinfo.public_id,   pub_id) 
3425          self.assertEqual(docinfo.system_url,  sys_id) 
3426          self.assertEqual(docinfo.root_name,   'html') 
3427          self.assertEqual(docinfo.doctype, doctype_string) 
3428   
3430          etree = self.etree 
3431          xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 
3432          sys_id = "some.dtd" 
3433          doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 
3434          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 
3435   
3436          tree = etree.parse(BytesIO(xml)) 
3437          docinfo = tree.docinfo 
3438          self.assertEqual(docinfo.encoding,    "UTF-8") 
3439          self.assertEqual(docinfo.xml_version, "1.0") 
3440          self.assertEqual(docinfo.public_id,   None) 
3441          self.assertEqual(docinfo.system_url,  sys_id) 
3442          self.assertEqual(docinfo.root_name,   'html') 
3443          self.assertEqual(docinfo.doctype, doctype_string) 
3444   
3446          etree = self.etree 
3447          xml = _bytes('<html><body></body></html>') 
3448          tree = etree.parse(BytesIO(xml)) 
3449          docinfo = tree.docinfo 
3450          self.assertEqual(docinfo.encoding,    "UTF-8") 
3451          self.assertEqual(docinfo.xml_version, "1.0") 
3452          self.assertEqual(docinfo.public_id,   None) 
3453          self.assertEqual(docinfo.system_url,  None) 
3454          self.assertEqual(docinfo.root_name,   'html') 
3455          self.assertEqual(docinfo.doctype, '') 
3456   
3458          etree = self.etree 
3459          xml = _bytes('<!DOCTYPE root><root></root>') 
3460          tree = etree.parse(BytesIO(xml)) 
3461          docinfo = tree.docinfo 
3462          self.assertEqual(docinfo.encoding,    "UTF-8") 
3463          self.assertEqual(docinfo.xml_version, "1.0") 
3464          self.assertEqual(docinfo.public_id,   None) 
3465          self.assertEqual(docinfo.system_url,  None) 
3466          self.assertEqual(docinfo.root_name,   'root') 
3467          self.assertEqual(docinfo.doctype, '<!DOCTYPE root>') 
3468   
3470          etree = self.etree 
3471          xml = _bytes('<!DOCTYPE root>\n<root/>') 
3472          tree = etree.parse(BytesIO(xml)) 
3473          self.assertEqual(xml, etree.tostring(tree)) 
3474   
3476          etree = self.etree 
3477          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 
3478          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 
3479          doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)) 
3480   
3481          xml = _bytes('<!DOCTYPE root>\n<root/>') 
3482          tree = etree.parse(BytesIO(xml)) 
3483          self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string), 
3484                            etree.tostring(tree, doctype=doctype_string)) 
3485   
3487          etree = self.etree 
3488          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 
3489          self.assertEqual(root.base, "http://no/such/url") 
3490          self.assertEqual( 
3491              root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 
3492          root.base = "https://secret/url" 
3493          self.assertEqual(root.base, "https://secret/url") 
3494          self.assertEqual( 
3495              root.get('{http://www.w3.org/XML/1998/namespace}base'), 
3496              "https://secret/url") 
3497   
3499          etree = self.etree 
3500          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 
3501          self.assertEqual(root.base, "http://no/such/url") 
3502          self.assertEqual( 
3503              root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 
3504          root.set('{http://www.w3.org/XML/1998/namespace}base', 
3505                   "https://secret/url") 
3506          self.assertEqual(root.base, "https://secret/url") 
3507          self.assertEqual( 
3508              root.get('{http://www.w3.org/XML/1998/namespace}base'), 
3509              "https://secret/url") 
3510   
3512          etree = self.etree 
3513          root = etree.HTML(_bytes("<html><body></body></html>"), 
3514                            base_url="http://no/such/url") 
3515          self.assertEqual(root.base, "http://no/such/url") 
3516   
3518          etree = self.etree 
3519          root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>')) 
3520          self.assertEqual(root.base, "http://no/such/url") 
3521   
3523          # parse from a file object that returns unicode strings 
3524          f = LargeFileLikeUnicode() 
3525          tree = self.etree.parse(f) 
3526          root = tree.getroot() 
3527          self.assertTrue(root.tag.endswith('root')) 
3528   
3530          # check that DTDs that go in also go back out 
3531          xml = _bytes('''\ 
3532          <!DOCTYPE test SYSTEM "test.dtd" [ 
3533            <!ENTITY entity "tasty"> 
3534            <!ELEMENT test (a)> 
3535            <!ELEMENT a (#PCDATA)> 
3536          ]> 
3537          <test><a>test-test</a></test>\ 
3538          ''') 
3539          tree = self.etree.parse(BytesIO(xml)) 
3540          self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")), 
3541                           xml.replace(_bytes(" "), _bytes(""))) 
3542   
3544          Element = self.etree.Element 
3545   
3546          a = Element('a') 
3547          self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho') 
3548          self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho') 
3549   
3550          self.assertRaises(ValueError, Element, 'ha\0ho') 
3551   
3553          Element = self.etree.Element 
3554   
3555          a = Element('a') 
3556          self.assertRaises(ValueError, setattr, a, "text", 
3557                            _str('ha\0ho')) 
3558          self.assertRaises(ValueError, setattr, a, "tail", 
3559                            _str('ha\0ho')) 
3560   
3561          self.assertRaises(ValueError, Element, 
3562                            _str('ha\0ho')) 
3563   
3565          Element = self.etree.Element 
3566   
3567          a = Element('a') 
3568          self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho') 
3569          self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho') 
3570   
3571          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho') 
3572          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho') 
3573   
3574          self.assertRaises(ValueError, Element, 'ha\x07ho') 
3575          self.assertRaises(ValueError, Element, 'ha\x02ho') 
3576   
3578          Element = self.etree.Element 
3579   
3580          a = Element('a') 
3581          self.assertRaises(ValueError, setattr, a, "text", 
3582                            _str('ha\x07ho')) 
3583          self.assertRaises(ValueError, setattr, a, "text", 
3584                            _str('ha\x02ho')) 
3585   
3586          self.assertRaises(ValueError, setattr, a, "tail", 
3587                            _str('ha\x07ho')) 
3588          self.assertRaises(ValueError, setattr, a, "tail", 
3589                            _str('ha\x02ho')) 
3590   
3591          self.assertRaises(ValueError, Element, 
3592                            _str('ha\x07ho')) 
3593          self.assertRaises(ValueError, Element, 
3594                            _str('ha\x02ho')) 
3595   
3597          Element = self.etree.Element 
3598   
3599          a = Element('a') 
3600          self.assertRaises(ValueError, setattr, a, "text", 
3601                            _str('ha\u1234\x07ho')) 
3602          self.assertRaises(ValueError, setattr, a, "text", 
3603                            _str('ha\u1234\x02ho')) 
3604   
3605          self.assertRaises(ValueError, setattr, a, "tail", 
3606                            _str('ha\u1234\x07ho')) 
3607          self.assertRaises(ValueError, setattr, a, "tail", 
3608                            _str('ha\u1234\x02ho')) 
3609   
3610          self.assertRaises(ValueError, Element, 
3611                            _str('ha\u1234\x07ho')) 
3612          self.assertRaises(ValueError, Element, 
3613                            _str('ha\u1234\x02ho')) 
3614   
3616          # ElementTree fails to serialize this 
3617          tostring = self.etree.tostring 
3618          Element = self.etree.Element 
3619          SubElement = self.etree.SubElement 
3620           
3621          a = Element('a') 
3622          b = SubElement(a, 'b') 
3623          c = SubElement(a, 'c') 
3624   
3625          result = tostring(a, encoding='UTF-16') 
3626          self.assertEqual(_bytes('<a><b></b><c></c></a>'), 
3627                            canonicalize(result)) 
3628   
3630          # ElementTree raises an AssertionError here 
3631          tostring = self.etree.tostring 
3632          self.assertRaises(TypeError, self.etree.tostring, None) 
3633   
3635          tostring = self.etree.tostring 
3636          Element = self.etree.Element 
3637          SubElement = self.etree.SubElement 
3638   
3639          a = Element('a') 
3640          b = SubElement(a, 'b') 
3641          c = SubElement(a, 'c') 
3642   
3643          result = tostring(a) 
3644          self.assertEqual(result, _bytes("<a><b/><c/></a>")) 
3645   
3646          result = tostring(a, pretty_print=False) 
3647          self.assertEqual(result, _bytes("<a><b/><c/></a>")) 
3648   
3649          result = tostring(a, pretty_print=True) 
3650          self.assertEqual(result, _bytes("<a>\n  <b/>\n  <c/>\n</a>\n")) 
3651   
3653          tostring = self.etree.tostring 
3654          Element = self.etree.Element 
3655          SubElement = self.etree.SubElement 
3656   
3657          a = Element('a') 
3658          a.tail = "aTAIL" 
3659          b = SubElement(a, 'b') 
3660          b.tail = "bTAIL" 
3661          c = SubElement(a, 'c') 
3662   
3663          result = tostring(a) 
3664          self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL")) 
3665   
3666          result = tostring(a, with_tail=False) 
3667          self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>")) 
3668   
3669          result = tostring(a, with_tail=True) 
3670          self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL")) 
3671   
3673          tostring = self.etree.tostring 
3674          html = self.etree.fromstring( 
3675              '<html><body>' 
3676              '<div><p>Some text<i>\r\n</i></p></div>\r\n' 
3677              '</body></html>', 
3678              parser=self.etree.HTMLParser()) 
3679          self.assertEqual(html.tag, 'html') 
3680          div = html.find('.//div') 
3681          self.assertEqual(div.tail, '\r\n') 
3682          result = tostring(div, method='html') 
3683          self.assertEqual( 
3684              result, 
3685              _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n")) 
3686          result = tostring(div, method='html', with_tail=True) 
3687          self.assertEqual( 
3688              result, 
3689              _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n")) 
3690          result = tostring(div, method='html', with_tail=False) 
3691          self.assertEqual( 
3692              result, 
3693              _bytes("<div><p>Some text<i>\r\n</i></p></div>")) 
3694   
3696          tostring = self.etree.tostring 
3697          XML = self.etree.XML 
3698          ElementTree = self.etree.ElementTree 
3699          Element = self.etree.Element 
3700   
3701          tree = Element("root").getroottree() 
3702          self.assertEqual(None, tree.docinfo.standalone) 
3703   
3704          tree = XML(_bytes("<root/>")).getroottree() 
3705          self.assertEqual(None, tree.docinfo.standalone) 
3706   
3707          tree = XML(_bytes( 
3708              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>" 
3709              )).getroottree() 
3710          self.assertEqual(True, tree.docinfo.standalone) 
3711   
3712          tree = XML(_bytes( 
3713              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>" 
3714              )).getroottree() 
3715          self.assertEqual(False, tree.docinfo.standalone) 
3716   
3718          tostring = self.etree.tostring 
3719          XML = self.etree.XML 
3720          ElementTree = self.etree.ElementTree 
3721   
3722          root = XML(_bytes("<root/>")) 
3723   
3724          tree = ElementTree(root) 
3725          self.assertEqual(None, tree.docinfo.standalone) 
3726   
3727          result = tostring(root, xml_declaration=True, encoding="ASCII") 
3728          self.assertEqual(result, _bytes( 
3729              "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 
3730   
3731          result = tostring(root, xml_declaration=True, encoding="ASCII", 
3732                            standalone=True) 
3733          self.assertEqual(result, _bytes( 
3734              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>")) 
3735   
3736          tree = ElementTree(XML(result)) 
3737          self.assertEqual(True, tree.docinfo.standalone) 
3738   
3739          result = tostring(root, xml_declaration=True, encoding="ASCII", 
3740                            standalone=False) 
3741          self.assertEqual(result, _bytes( 
3742              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>")) 
3743   
3744          tree = ElementTree(XML(result)) 
3745          self.assertEqual(False, tree.docinfo.standalone) 
3746   
3748          tostring = self.etree.tostring 
3749          XML = self.etree.XML 
3750          ElementTree = self.etree.ElementTree 
3751   
3752          root = XML(_bytes( 
3753              "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>")) 
3754   
3755          tree = ElementTree(root) 
3756          self.assertEqual(True, tree.docinfo.standalone) 
3757   
3758          result = tostring(root, xml_declaration=True, encoding="ASCII") 
3759          self.assertEqual(result, _bytes( 
3760              "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 
3761   
3762          result = tostring(root, xml_declaration=True, encoding="ASCII", 
3763                            standalone=True) 
3764          self.assertEqual(result, _bytes( 
3765              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>")) 
3766   
3768          tostring = self.etree.tostring 
3769          Element = self.etree.Element 
3770          SubElement = self.etree.SubElement 
3771           
3772          a = Element('a') 
3773          a.text = "A" 
3774          a.tail = "tail" 
3775          b = SubElement(a, 'b') 
3776          b.text = "B" 
3777          b.tail = _str("Søk på nettet") 
3778          c = SubElement(a, 'c') 
3779          c.text = "C" 
3780   
3781          result = tostring(a, method="text", encoding="UTF-16") 
3782   
3783          self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"), 
3784                            result) 
3785   
3787          tostring = self.etree.tostring 
3788          Element = self.etree.Element 
3789          SubElement = self.etree.SubElement 
3790           
3791          a = Element('a') 
3792          a.text = _str('Søk på nettetA') 
3793          a.tail = "tail" 
3794          b = SubElement(a, 'b') 
3795          b.text = "B" 
3796          b.tail = _str('Søk på nettetB') 
3797          c = SubElement(a, 'c') 
3798          c.text = "C" 
3799           
3800          self.assertRaises(UnicodeEncodeError, 
3801                            tostring, a, method="text") 
3802           
3803          self.assertEqual( 
3804              _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'), 
3805              tostring(a, encoding="UTF-8", method="text")) 
3806   
3808          tounicode = self.etree.tounicode 
3809          Element = self.etree.Element 
3810          SubElement = self.etree.SubElement 
3811           
3812          a = Element('a') 
3813          b = SubElement(a, 'b') 
3814          c = SubElement(a, 'c') 
3815           
3816          self.assertTrue(isinstance(tounicode(a), _unicode)) 
3817          self.assertEqual(_bytes('<a><b></b><c></c></a>'), 
3818                            canonicalize(tounicode(a))) 
3819   
3821          tounicode = self.etree.tounicode 
3822          Element = self.etree.Element 
3823          SubElement = self.etree.SubElement 
3824           
3825          a = Element('a') 
3826          b = SubElement(a, 'b') 
3827          c = SubElement(a, 'c') 
3828          d = SubElement(c, 'd') 
3829          self.assertTrue(isinstance(tounicode(b), _unicode)) 
3830          self.assertTrue(isinstance(tounicode(c), _unicode)) 
3831          self.assertEqual(_bytes('<b></b>'), 
3832                            canonicalize(tounicode(b))) 
3833          self.assertEqual(_bytes('<c><d></d></c>'), 
3834                            canonicalize(tounicode(c))) 
3835   
3839   
3841          tounicode = self.etree.tounicode 
3842          Element = self.etree.Element 
3843          SubElement = self.etree.SubElement 
3844           
3845          a = Element('a') 
3846          b = SubElement(a, 'b') 
3847          c = SubElement(a, 'c') 
3848          d = SubElement(c, 'd') 
3849          b.tail = 'Foo' 
3850   
3851          self.assertTrue(isinstance(tounicode(b), _unicode)) 
3852          self.assertTrue(tounicode(b) == '<b/>Foo' or 
3853                       tounicode(b) == '<b />Foo') 
3854   
3856          tounicode = self.etree.tounicode 
3857          Element = self.etree.Element 
3858          SubElement = self.etree.SubElement 
3859   
3860          a = Element('a') 
3861          b = SubElement(a, 'b') 
3862          c = SubElement(a, 'c') 
3863   
3864          result = tounicode(a) 
3865          self.assertEqual(result, "<a><b/><c/></a>") 
3866   
3867          result = tounicode(a, pretty_print=False) 
3868          self.assertEqual(result, "<a><b/><c/></a>") 
3869   
3870          result = tounicode(a, pretty_print=True) 
3871          self.assertEqual(result, "<a>\n  <b/>\n  <c/>\n</a>\n") 
3872   
3874          tostring = self.etree.tostring 
3875          Element = self.etree.Element 
3876          SubElement = self.etree.SubElement 
3877           
3878          a = Element('a') 
3879          b = SubElement(a, 'b') 
3880          c = SubElement(a, 'c') 
3881           
3882          self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode)) 
3883          self.assertEqual(_bytes('<a><b></b><c></c></a>'), 
3884                            canonicalize(tostring(a, encoding=_unicode))) 
3885   
3887          tostring = self.etree.tostring 
3888          Element = self.etree.Element 
3889          SubElement = self.etree.SubElement 
3890           
3891          a = Element('a') 
3892          b = SubElement(a, 'b') 
3893          c = SubElement(a, 'c') 
3894          d = SubElement(c, 'd') 
3895          self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 
3896          self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode)) 
3897          self.assertEqual(_bytes('<b></b>'), 
3898                            canonicalize(tostring(b, encoding=_unicode))) 
3899          self.assertEqual(_bytes('<c><d></d></c>'), 
3900                            canonicalize(tostring(c, encoding=_unicode))) 
3901   
3903          tostring = self.etree.tostring 
3904          self.assertRaises(TypeError, self.etree.tostring, 
3905                            None, encoding=_unicode) 
3906   
3908          tostring = self.etree.tostring 
3909          Element = self.etree.Element 
3910          SubElement = self.etree.SubElement 
3911           
3912          a = Element('a') 
3913          b = SubElement(a, 'b') 
3914          c = SubElement(a, 'c') 
3915          d = SubElement(c, 'd') 
3916          b.tail = 'Foo' 
3917   
3918          self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 
3919          self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or 
3920                       tostring(b, encoding=_unicode) == '<b />Foo') 
3921   
3923          tostring = self.etree.tostring 
3924          Element = self.etree.Element 
3925          SubElement = self.etree.SubElement 
3926   
3927          a = Element('a') 
3928          b = SubElement(a, 'b') 
3929          c = SubElement(a, 'c') 
3930   
3931          result = tostring(a, encoding=_unicode) 
3932          self.assertEqual(result, "<a><b/><c/></a>") 
3933   
3934          result = tostring(a, encoding=_unicode, pretty_print=False) 
3935          self.assertEqual(result, "<a><b/><c/></a>") 
3936   
3937          result = tostring(a, encoding=_unicode, pretty_print=True) 
3938          self.assertEqual(result, "<a>\n  <b/>\n  <c/>\n</a>\n") 
3939   
3941          root = etree.Element('parent') 
3942          etree.SubElement(root, 'child') 
3943   
3944          self.assertEqual(len(root), 1) 
3945          self.assertEqual(root[0].tag, 'child') 
3946   
3947          # in PyPy, GC used to kill the Python proxy instance without cleanup 
3948          gc.collect() 
3949          self.assertEqual(len(root), 1) 
3950          self.assertEqual(root[0].tag, 'child') 
3951   
3955   
3956          el1 = SubEl() 
3957          el2 = SubEl() 
3958          self.assertEqual('SubEl', el1.tag) 
3959          self.assertEqual('SubEl', el2.tag) 
3960          el1.other = el2 
3961          el2.other = el1 
3962   
3963          del el1, el2 
3964          gc.collect() 
3965          # not really testing anything here, but it shouldn't crash 
3966   
3968          root = etree.Element('parent') 
3969          c1 = etree.SubElement(root, 'child1') 
3970          c2 = etree.SubElement(root, 'child2') 
3971   
3972          root.remove(c1) 
3973          root.remove(c2) 
3974          c1.addnext(c2) 
3975          del c1 
3976          # trigger deallocation attempt of c1 
3977          c2.getprevious() 
3978          # make sure it wasn't deallocated 
3979          self.assertEqual('child1', c2.getprevious().tag) 
3980   
3982          root = etree.Element('parent') 
3983          c1 = etree.SubElement(root, 'child1') 
3984          c2 = etree.SubElement(root, 'child2') 
3985   
3986          root.remove(c1) 
3987          root.remove(c2) 
3988          c1.addnext(c2) 
3989          c1.tail = 'abc' 
3990          c2.tail = 'xyz' 
3991          del c1 
3992          # trigger deallocation attempt of c1 
3993          c2.getprevious() 
3994          # make sure it wasn't deallocated 
3995          self.assertEqual('child1', c2.getprevious().tag) 
3996          self.assertEqual('abc', c2.getprevious().tail) 
3997   
3998      # helper methods 
3999   
4001          """Write out element for comparison. 
4002          """ 
4003          ElementTree = self.etree.ElementTree 
4004          f = BytesIO() 
4005          tree = ElementTree(element=element) 
4006          tree.write(f, encoding=encoding, compression=compression) 
4007          data = f.getvalue() 
4008          if compression: 
4009              data = zlib.decompress(data) 
4010          return canonicalize(data) 
4011   
4015          filename = fileInTestDir('test_broken.xml') 
4016          root = etree.XML(_bytes('''\ 
4017          <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 
4018            <xi:include href="%s" parse="text"/> 
4019          </doc> 
4020          ''' % path2url(filename))) 
4021          old_text = root.text 
4022          content = read_file(filename) 
4023          old_tail = root[0].tail 
4024   
4025          self.include( etree.ElementTree(root) ) 
4026          self.assertEqual(old_text + content + old_tail, 
4027                            root.text) 
4028   
4030          tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 
4031          self.assertNotEqual( 
4032              'a', 
4033              tree.getroot()[1].tag) 
4034          # process xincludes 
4035          self.include( tree ) 
4036          # check whether we find it replaced with included data 
4037          self.assertEqual( 
4038              'a', 
4039              tree.getroot()[1].tag) 
4040   
4042          class res(etree.Resolver): 
4043              include_text = read_file(fileInTestDir('test.xml')) 
4044              called = {} 
4045              def resolve(self, url, id, context): 
4046                  if url.endswith(".dtd"): 
4047                      self.called["dtd"] = True 
4048                      return self.resolve_filename( 
4049                          fileInTestDir('test.dtd'), context) 
4050                  elif url.endswith("test_xinclude.xml"): 
4051                      self.called["input"] = True 
4052                      return None # delegate to default resolver 
4053                  else: 
4054                      self.called["include"] = True 
4055                      return self.resolve_string(self.include_text, context) 
4056   
4057          res_instance = res() 
4058          parser = etree.XMLParser(load_dtd = True) 
4059          parser.resolvers.add(res_instance) 
4060   
4061          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 
4062                             parser = parser) 
4063   
4064          self.include(tree) 
4065   
4066          called = list(res_instance.called.items()) 
4067          called.sort() 
4068          self.assertEqual( 
4069              [("dtd", True), ("include", True), ("input", True)], 
4070              called) 
4071   
4073          data = textwrap.dedent(''' 
4074          <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 
4075          <foo/> 
4076          <xi:include href="./test.xml" /> 
4077          </doc> 
4078          ''') 
4079   
4080          class Resolver(etree.Resolver): 
4081              called = {} 
4082   
4083              def resolve(self, url, id, context): 
4084                  if url.endswith("test_xinclude.xml"): 
4085                      assert not self.called.get("input") 
4086                      self.called["input"] = True 
4087                      return None  # delegate to default resolver 
4088                  elif url.endswith('/test5.xml'): 
4089                      assert not self.called.get("DONE") 
4090                      self.called["DONE"] = True 
4091                      return self.resolve_string('<DONE/>', context) 
4092                  else: 
4093                      _, filename = url.rsplit('/', 1) 
4094                      assert not self.called.get(filename) 
4095                      self.called[filename] = True 
4096                      next_data = data.replace( 
4097                          'test.xml', 'test%d.xml' % len(self.called)) 
4098                      return self.resolve_string(next_data, context) 
4099   
4100          res_instance = Resolver() 
4101          parser = etree.XMLParser(load_dtd=True) 
4102          parser.resolvers.add(res_instance) 
4103   
4104          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 
4105                             parser=parser) 
4106   
4107          self.include(tree) 
4108   
4109          called = list(res_instance.called.items()) 
4110          called.sort() 
4111          self.assertEqual( 
4112              [("DONE", True), ("input", True), ("test.xml", True), 
4113               ("test2.xml", True), ("test3.xml", True), ("test4.xml", True)], 
4114              called) 
4115   
4120   
4126   
4130          tree = self.parse(_bytes('<a><b/></a>')) 
4131          f = BytesIO() 
4132          tree.write_c14n(f) 
4133          s = f.getvalue() 
4134          self.assertEqual(_bytes('<a><b></b></a>'), 
4135                            s) 
4136   
4138          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4139          f = BytesIO() 
4140          tree.write_c14n(f, compression=9) 
4141          with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile: 
4142              s = gzfile.read() 
4143          self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 
4144                            s) 
4145   
4147          tree = self.parse(_bytes('<a><b/></a>')) 
4148          with tmpfile() as filename: 
4149              tree.write_c14n(filename) 
4150              data = read_file(filename, 'rb') 
4151          self.assertEqual(_bytes('<a><b></b></a>'), 
4152                            data) 
4153   
4155          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4156          with tmpfile() as filename: 
4157              tree.write_c14n(filename, compression=9) 
4158              with closing(gzip.open(filename, 'rb')) as f: 
4159                  data = f.read() 
4160          self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 
4161                            data) 
4162   
4164          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 
4165          f = BytesIO() 
4166          tree.write_c14n(f) 
4167          s = f.getvalue() 
4168          self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 
4169                            s) 
4170          f = BytesIO() 
4171          tree.write_c14n(f, with_comments=True) 
4172          s = f.getvalue() 
4173          self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 
4174                            s) 
4175          f = BytesIO() 
4176          tree.write_c14n(f, with_comments=False) 
4177          s = f.getvalue() 
4178          self.assertEqual(_bytes('<a><b></b></a>'), 
4179                            s) 
4180   
4182          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 
4183          s = etree.tostring(tree, method='c14n') 
4184          self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 
4185                            s) 
4186          s = etree.tostring(tree, method='c14n', with_comments=True) 
4187          self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 
4188                            s) 
4189          s = etree.tostring(tree, method='c14n', with_comments=False) 
4190          self.assertEqual(_bytes('<a><b></b></a>'), 
4191                            s) 
4192   
4194          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 
4195          s = etree.tostring(tree.getroot(), method='c14n') 
4196          self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 
4197                            s) 
4198          s = etree.tostring(tree.getroot(), method='c14n', with_comments=True) 
4199          self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 
4200                            s) 
4201          s = etree.tostring(tree.getroot(), method='c14n', with_comments=False) 
4202          self.assertEqual(_bytes('<a><b></b></a>'), 
4203                            s) 
4204   
4206          tree = self.parse(_bytes( 
4207                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 
4208          f = BytesIO() 
4209          tree.write_c14n(f) 
4210          s = f.getvalue() 
4211          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4212                            s) 
4213          f = BytesIO() 
4214          tree.write_c14n(f, exclusive=False) 
4215          s = f.getvalue() 
4216          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4217                            s) 
4218          f = BytesIO() 
4219          tree.write_c14n(f, exclusive=True) 
4220          s = f.getvalue() 
4221          self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 
4222                            s) 
4223   
4224          f = BytesIO() 
4225          tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z']) 
4226          s = f.getvalue() 
4227          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'), 
4228                            s) 
4229   
4231          tree = self.parse(_bytes( 
4232                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 
4233          s = etree.tostring(tree, method='c14n') 
4234          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4235                            s) 
4236          s = etree.tostring(tree, method='c14n', exclusive=False) 
4237          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4238                            s) 
4239          s = etree.tostring(tree, method='c14n', exclusive=True) 
4240          self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 
4241                            s) 
4242   
4243          s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 
4244          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'), 
4245                            s) 
4246   
4248          tree = self.parse(_bytes( 
4249                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 
4250          s = etree.tostring(tree.getroot(), method='c14n') 
4251          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4252                            s) 
4253          s = etree.tostring(tree.getroot(), method='c14n', exclusive=False) 
4254          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4255                            s) 
4256          s = etree.tostring(tree.getroot(), method='c14n', exclusive=True) 
4257          self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 
4258                            s) 
4259   
4260          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False) 
4261          self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 
4262                            s) 
4263          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True) 
4264          self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'), 
4265                            s) 
4266   
4267          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 
4268          self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 
4269                            s) 
4270   
4272          """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)""" 
4273          tree = self.parse(_bytes( 
4274                  '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 
4275   
4276          s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z']) 
4277          self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4278                            s) 
4279   
4283          tree = self.parse(_bytes('<a><b/></a>')) 
4284          f = BytesIO() 
4285          tree.write(f) 
4286          s = f.getvalue() 
4287          self.assertEqual(_bytes('<a><b/></a>'), 
4288                            s) 
4289   
4291          tree = self.parse(_bytes('<a><b/></a>')) 
4292          f = BytesIO() 
4293          tree.write(f, doctype='HUHU') 
4294          s = f.getvalue() 
4295          self.assertEqual(_bytes('HUHU\n<a><b/></a>'), 
4296                            s) 
4297   
4299          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4300          f = BytesIO() 
4301          tree.write(f, compression=9) 
4302          with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile: 
4303              s = gzfile.read() 
4304          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4305                            s) 
4306   
4308          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4309          f = BytesIO() 
4310          tree.write(f, compression=9, doctype='<!DOCTYPE a>') 
4311          with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile: 
4312              s = gzfile.read() 
4313          self.assertEqual(_bytes('<!DOCTYPE a>\n<a>'+'<b/>'*200+'</a>'), 
4314                            s) 
4315   
4317          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4318          f = BytesIO() 
4319          tree.write(f, compression=0) 
4320          s0 = f.getvalue() 
4321   
4322          f = BytesIO() 
4323          tree.write(f) 
4324          self.assertEqual(f.getvalue(), s0) 
4325   
4326          f = BytesIO() 
4327          tree.write(f, compression=1) 
4328          s = f.getvalue() 
4329          self.assertTrue(len(s) <= len(s0)) 
4330          with closing(gzip.GzipFile(fileobj=BytesIO(s))) as gzfile: 
4331              s1 = gzfile.read() 
4332   
4333          f = BytesIO() 
4334          tree.write(f, compression=9) 
4335          s = f.getvalue() 
4336          self.assertTrue(len(s) <= len(s0)) 
4337          with closing(gzip.GzipFile(fileobj=BytesIO(s))) as gzfile: 
4338              s9 = gzfile.read() 
4339   
4340          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4341                            s0) 
4342          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4343                            s1) 
4344          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4345                            s9) 
4346   
4348          tree = self.parse(_bytes('<a><b/></a>')) 
4349          with tmpfile() as filename: 
4350              tree.write(filename) 
4351              data = read_file(filename, 'rb') 
4352          self.assertEqual(_bytes('<a><b/></a>'), 
4353                            data) 
4354   
4356          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4357          with tmpfile() as filename: 
4358              tree.write(filename, compression=9) 
4359              with closing(gzip.open(filename, 'rb')) as f: 
4360                  data = f.read() 
4361          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4362                            data) 
4363   
4365          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4366          with tmpfile() as filename: 
4367              tree.write(filename, compression=9) 
4368              data = etree.tostring(etree.parse(filename)) 
4369          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4370                            data) 
4371   
4380   
4383      etree = etree 
4384   
4386          parse = self.etree.parse 
4387          f = BytesIO('<a><b></c></b></a>') 
4388          self.etree.clear_error_log() 
4389          try: 
4390              parse(f) 
4391              logs = None 
4392          except SyntaxError: 
4393              e = sys.exc_info()[1] 
4394              logs = e.error_log 
4395          f.close() 
4396          self.assertTrue([ log for log in logs 
4397                         if 'mismatch' in log.message ]) 
4398          self.assertTrue([ log for log in logs 
4399                         if 'PARSER'   in log.domain_name]) 
4400          self.assertTrue([ log for log in logs 
4401                         if 'ERR_TAG_NAME_MISMATCH' in log.type_name ]) 
4402          self.assertTrue([ log for log in logs 
4403                         if 1 == log.line ]) 
4404          self.assertTrue([ log for log in logs 
4405                         if 15 == log.column ]) 
4406   
4417   
4418          self.etree.use_global_python_log(Logger()) 
4419          f = BytesIO('<a><b></c></b></a>') 
4420          try: 
4421              parse(f) 
4422          except SyntaxError: 
4423              pass 
4424          f.close() 
4425   
4426          self.assertTrue([ message for message in messages 
4427                         if 'mismatch' in message ]) 
4428          self.assertTrue([ message for message in messages 
4429                         if ':PARSER:'   in message]) 
4430          self.assertTrue([ message for message in messages 
4431                         if ':ERR_TAG_NAME_MISMATCH:' in message ]) 
4432          self.assertTrue([ message for message in messages 
4433                         if ':1:15:' in message ]) 
4434   
4449              def close(self): 
4450                  return 'close()' 
4451   
4452          parser = self.etree.XMLPullParser(target=Target()) 
4453          events = parser.read_events() 
4454   
4455          parser.feed('<root><element>') 
4456          self.assertFalse(list(events)) 
4457          self.assertFalse(list(events)) 
4458          parser.feed('</element><child>') 
4459          self.assertEqual([('end', 'end(element)')], list(events)) 
4460          parser.feed('</child>') 
4461          self.assertEqual([('end', 'end(child)')], list(events)) 
4462          parser.feed('</root>') 
4463          self.assertEqual([('end', 'end(root)')], list(events)) 
4464          self.assertFalse(list(events)) 
4465          self.assertEqual('close()', parser.close()) 
4466   
4471              def end(self, tag): 
4472                  return 'end(%s)' % tag 
4473              def close(self): 
4474                  return 'close()' 
4475   
4476          parser = self.etree.XMLPullParser( 
4477              ['start', 'end'], target=Target()) 
4478          events = parser.read_events() 
4479   
4480          parser.feed('<root><element>') 
4481          self.assertEqual( 
4482              [('start', 'start(root)'), ('start', 'start(element)')], 
4483              list(events)) 
4484          self.assertFalse(list(events)) 
4485          parser.feed('</element><child>') 
4486          self.assertEqual( 
4487              [('end', 'end(element)'), ('start', 'start(child)')], 
4488              list(events)) 
4489          parser.feed('</child>') 
4490          self.assertEqual( 
4491              [('end', 'end(child)')], 
4492              list(events)) 
4493          parser.feed('</root>') 
4494          self.assertEqual( 
4495              [('end', 'end(root)')], 
4496              list(events)) 
4497          self.assertFalse(list(events)) 
4498          self.assertEqual('close()', parser.close()) 
4499   
4501          parser = self.etree.XMLPullParser( 
4502              ['start', 'end'], target=etree.TreeBuilder()) 
4503          events = parser.read_events() 
4504   
4505          parser.feed('<root><element>') 
4506          self.assert_event_tags( 
4507              events, [('start', 'root'), ('start', 'element')]) 
4508          self.assertFalse(list(events)) 
4509          parser.feed('</element><child>') 
4510          self.assert_event_tags( 
4511              events, [('end', 'element'), ('start', 'child')]) 
4512          parser.feed('</child>') 
4513          self.assert_event_tags( 
4514              events, [('end', 'child')]) 
4515          parser.feed('</root>') 
4516          self.assert_event_tags( 
4517              events, [('end', 'root')]) 
4518          self.assertFalse(list(events)) 
4519          root = parser.close() 
4520          self.assertEqual('root', root.tag) 
4521   
4523          class Target(etree.TreeBuilder): 
4524              def end(self, tag): 
4525                  el = super(Target, self).end(tag) 
4526                  el.tag += '-huhu' 
4527                  return el 
4528   
4529          parser = self.etree.XMLPullParser( 
4530              ['start', 'end'], target=Target()) 
4531          events = parser.read_events() 
4532   
4533          parser.feed('<root><element>') 
4534          self.assert_event_tags( 
4535              events, [('start', 'root'), ('start', 'element')]) 
4536          self.assertFalse(list(events)) 
4537          parser.feed('</element><child>') 
4538          self.assert_event_tags( 
4539              events, [('end', 'element-huhu'), ('start', 'child')]) 
4540          parser.feed('</child>') 
4541          self.assert_event_tags( 
4542              events, [('end', 'child-huhu')]) 
4543          parser.feed('</root>') 
4544          self.assert_event_tags( 
4545              events, [('end', 'root-huhu')]) 
4546          self.assertFalse(list(events)) 
4547          root = parser.close() 
4548          self.assertEqual('root-huhu', root.tag) 
4549   
4552      suite = unittest.TestSuite() 
4553      suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 
4554      suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 
4555      suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 
4556      suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 
4557      suite.addTests([unittest.makeSuite(ETreeWriteTestCase)]) 
4558      suite.addTests([unittest.makeSuite(ETreeErrorLogTest)]) 
4559      suite.addTests([unittest.makeSuite(XMLPullParserTest)]) 
4560   
4561      # add original doctests from ElementTree selftest modules 
4562      from . import selftest, selftest2 
4563      suite.addTests(doctest.DocTestSuite(selftest)) 
4564      suite.addTests(doctest.DocTestSuite(selftest2)) 
4565   
4566      # add doctests 
4567      suite.addTests(doctest.DocTestSuite(etree)) 
4568      suite.addTests( 
4569          [make_doctest('../../../doc/tutorial.txt')]) 
4570      if sys.version_info >= (2,6): 
4571          # now requires the 'with' statement 
4572          suite.addTests( 
4573              [make_doctest('../../../doc/api.txt')]) 
4574      suite.addTests( 
4575          [make_doctest('../../../doc/FAQ.txt')]) 
4576      suite.addTests( 
4577          [make_doctest('../../../doc/parsing.txt')]) 
4578      suite.addTests( 
4579          [make_doctest('../../../doc/resolvers.txt')]) 
4580      return suite 
4581   
4582   
4583  if __name__ == '__main__': 
4584      print('to test use test.py %s' % __file__) 
4585   
| Home | Trees | Indices | Help | 
 | 
|---|
| Generated by Epydoc 3.0.1 on Fri Nov 24 17:07:07 2017 | http://epydoc.sourceforge.net |