| 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><d/></b><c/></a>')) 
1218   
1219          counts = [] 
1220          for event, elem in iterwalk(root): 
1221              counts.append(len(list(elem.getiterator()))) 
1222          self.assertEqual( 
1223              [1,2,1,4], 
1224              counts) 
1225   
1227          parse = self.etree.parse 
1228          parser = self.etree.XMLParser(dtd_validation=True) 
1229          assertEqual = self.assertEqual 
1230          test_url = _str("__nosuch.dtd") 
1231   
1232          class MyResolver(self.etree.Resolver): 
1233              def resolve(self, url, id, context): 
1234                  assertEqual(url, test_url) 
1235                  return self.resolve_string( 
1236                      _str('''<!ENTITY myentity "%s"> 
1237                          <!ELEMENT doc ANY>''') % url, context) 
1238   
1239          parser.resolvers.add(MyResolver()) 
1240   
1241          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 
1242          tree = parse(StringIO(xml), parser) 
1243          root = tree.getroot() 
1244          self.assertEqual(root.text, test_url) 
1245   
1247          parse = self.etree.parse 
1248          parser = self.etree.XMLParser(dtd_validation=True) 
1249          assertEqual = self.assertEqual 
1250          test_url = _str("__nosuch.dtd") 
1251   
1252          class MyResolver(self.etree.Resolver): 
1253              def resolve(self, url, id, context): 
1254                  assertEqual(url, test_url) 
1255                  return self.resolve_string( 
1256                      (_str('''<!ENTITY myentity "%s"> 
1257                               <!ELEMENT doc ANY>''') % url).encode('utf-8'), 
1258                      context) 
1259   
1260          parser.resolvers.add(MyResolver()) 
1261   
1262          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 
1263          tree = parse(StringIO(xml), parser) 
1264          root = tree.getroot() 
1265          self.assertEqual(root.text, test_url) 
1266   
1268          parse = self.etree.parse 
1269          parser = self.etree.XMLParser(dtd_validation=True) 
1270          assertEqual = self.assertEqual 
1271          test_url = _str("__nosuch.dtd") 
1272   
1273          class MyResolver(self.etree.Resolver): 
1274              def resolve(self, url, id, context): 
1275                  assertEqual(url, test_url) 
1276                  return self.resolve_file( 
1277                      SillyFileLike( 
1278                          _str('''<!ENTITY myentity "%s"> 
1279                          <!ELEMENT doc ANY>''') % url), context) 
1280   
1281          parser.resolvers.add(MyResolver()) 
1282   
1283          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 
1284          tree = parse(StringIO(xml), parser) 
1285          root = tree.getroot() 
1286          self.assertEqual(root.text, test_url) 
1287   
1289          parse = self.etree.parse 
1290          parser = self.etree.XMLParser(attribute_defaults=True) 
1291          assertEqual = self.assertEqual 
1292          test_url = _str("__nosuch.dtd") 
1293   
1294          class MyResolver(self.etree.Resolver): 
1295              def resolve(self, url, id, context): 
1296                  assertEqual(url, test_url) 
1297                  return self.resolve_filename( 
1298                      fileInTestDir('test.dtd'), context) 
1299   
1300          parser.resolvers.add(MyResolver()) 
1301   
1302          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 
1303          tree = parse(StringIO(xml), parser) 
1304          root = tree.getroot() 
1305          self.assertEqual( 
1306              root.attrib,    {'default': 'valueA'}) 
1307          self.assertEqual( 
1308              root[0].attrib, {'default': 'valueB'}) 
1309   
1311          parse = self.etree.parse 
1312          parser = self.etree.XMLParser(attribute_defaults=True) 
1313          assertEqual = self.assertEqual 
1314          test_url = _str("__nosuch.dtd") 
1315   
1316          class MyResolver(self.etree.Resolver): 
1317              def resolve(self, url, id, context): 
1318                  expected = fileUrlInTestDir(test_url) 
1319                  url = url.replace('file://', 'file:')  # depends on libxml2 version 
1320                  expected = expected.replace('file://', 'file:') 
1321                  assertEqual(url, expected) 
1322                  return self.resolve_filename( 
1323                      fileUrlInTestDir('test.dtd'), context) 
1324   
1325          parser.resolvers.add(MyResolver()) 
1326   
1327          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 
1328          tree = parse(StringIO(xml), parser, 
1329                       base_url=fileUrlInTestDir('__test.xml')) 
1330          root = tree.getroot() 
1331          self.assertEqual( 
1332              root.attrib,    {'default': 'valueA'}) 
1333          self.assertEqual( 
1334              root[0].attrib, {'default': 'valueB'}) 
1335   
1337          parse = self.etree.parse 
1338          parser = self.etree.XMLParser(attribute_defaults=True) 
1339          assertEqual = self.assertEqual 
1340          test_url = _str("__nosuch.dtd") 
1341   
1342          class MyResolver(self.etree.Resolver): 
1343              def resolve(self, url, id, context): 
1344                  assertEqual(url, test_url) 
1345                  return self.resolve_file( 
1346                      open(fileInTestDir('test.dtd'), 'rb'), context) 
1347   
1348          parser.resolvers.add(MyResolver()) 
1349   
1350          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url 
1351          tree = parse(StringIO(xml), parser) 
1352          root = tree.getroot() 
1353          self.assertEqual( 
1354              root.attrib,    {'default': 'valueA'}) 
1355          self.assertEqual( 
1356              root[0].attrib, {'default': 'valueB'}) 
1357   
1359          parse = self.etree.parse 
1360          parser = self.etree.XMLParser(load_dtd=True) 
1361          assertEqual = self.assertEqual 
1362          test_url = _str("__nosuch.dtd") 
1363   
1364          class check(object): 
1365              resolved = False 
1366   
1367          class MyResolver(self.etree.Resolver): 
1368              def resolve(self, url, id, context): 
1369                  assertEqual(url, test_url) 
1370                  check.resolved = True 
1371                  return self.resolve_empty(context) 
1372   
1373          parser.resolvers.add(MyResolver()) 
1374   
1375          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url 
1376          self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser) 
1377          self.assertTrue(check.resolved) 
1378   
1380          parse = self.etree.parse 
1381          parser = self.etree.XMLParser(dtd_validation=True) 
1382   
1383          class _LocalException(Exception): 
1384              pass 
1385   
1386          class MyResolver(self.etree.Resolver): 
1387              def resolve(self, url, id, context): 
1388                  raise _LocalException 
1389   
1390          parser.resolvers.add(MyResolver()) 
1391   
1392          xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>' 
1393          self.assertRaises(_LocalException, parse, BytesIO(xml), parser) 
1394   
1395      if etree.LIBXML_VERSION > (2,6,20): 
1397              parse = self.etree.parse 
1398              tostring = self.etree.tostring 
1399              parser = self.etree.XMLParser(resolve_entities=False) 
1400              Entity = self.etree.Entity 
1401   
1402              xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>') 
1403              tree = parse(BytesIO(xml), parser) 
1404              root = tree.getroot() 
1405              self.assertEqual(root[0].tag, Entity) 
1406              self.assertEqual(root[0].text, "&myentity;") 
1407              self.assertEqual(root[0].tail, None) 
1408              self.assertEqual(root[0].name, "myentity") 
1409   
1410              self.assertEqual(_bytes('<doc>&myentity;</doc>'), 
1411                                tostring(root)) 
1412   
1414              xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp " "> ]> 
1415                  <root> 
1416                    <child1/> 
1417                    <child2/> 
1418                    <child3> </child3> 
1419                  </root>''') 
1420   
1421              parser = self.etree.XMLParser(resolve_entities=False) 
1422              root = etree.fromstring(xml, parser) 
1423              self.assertEqual([ el.tag for el in root ], 
1424                                ['child1', 'child2', 'child3']) 
1425   
1426              root[0] = root[-1] 
1427              self.assertEqual([ el.tag for el in root ], 
1428                                ['child3', 'child2']) 
1429              self.assertEqual(root[0][0].text, ' ') 
1430              self.assertEqual(root[0][0].name, 'nbsp') 
1431   
1433          Entity = self.etree.Entity 
1434          Element = self.etree.Element 
1435          tostring = self.etree.tostring 
1436   
1437          root = Element("root") 
1438          root.append( Entity("test") ) 
1439   
1440          self.assertEqual(root[0].tag, Entity) 
1441          self.assertEqual(root[0].text, "&test;") 
1442          self.assertEqual(root[0].tail, None) 
1443          self.assertEqual(root[0].name, "test") 
1444   
1445          self.assertEqual(_bytes('<root>&test;</root>'), 
1446                            tostring(root)) 
1447   
1449          Entity = self.etree.Entity 
1450          self.assertEqual(Entity("test").text, '&test;') 
1451          self.assertEqual(Entity("#17683").text, '䔓') 
1452          self.assertEqual(Entity("#x1768").text, 'ᝨ') 
1453          self.assertEqual(Entity("#x98AF").text, '颯') 
1454   
1456          Entity = self.etree.Entity 
1457          self.assertRaises(ValueError, Entity, 'a b c') 
1458          self.assertRaises(ValueError, Entity, 'a,b') 
1459          self.assertRaises(ValueError, Entity, 'a\0b') 
1460          self.assertRaises(ValueError, Entity, '#abc') 
1461          self.assertRaises(ValueError, Entity, '#xxyz') 
1462   
1464          CDATA = self.etree.CDATA 
1465          Element = self.etree.Element 
1466          tostring = self.etree.tostring 
1467   
1468          root = Element("root") 
1469          root.text = CDATA('test') 
1470   
1471          self.assertEqual('test', 
1472                            root.text) 
1473          self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 
1474                            tostring(root)) 
1475   
1477          CDATA = self.etree.CDATA 
1478          Element = self.etree.Element 
1479          SubElement = self.etree.SubElement 
1480          tostring = self.etree.tostring 
1481   
1482          root = Element("root") 
1483          child = SubElement(root, 'child') 
1484          child.tail = CDATA('test') 
1485   
1486          self.assertEqual('test', child.tail) 
1487          self.assertEqual(_bytes('<root><child/><![CDATA[test]]></root>'), 
1488                           tostring(root)) 
1489   
1490          root = Element("root") 
1491          root.tail = CDATA('test') 
1492   
1493          self.assertEqual('test', root.tail) 
1494          self.assertEqual(_bytes('<root/><![CDATA[test]]>'), 
1495                           tostring(root)) 
1496   
1498          CDATA = self.etree.CDATA 
1499          Element = self.etree.Element 
1500          root = Element("root") 
1501   
1502          root.text = CDATA("test") 
1503          self.assertEqual('test', root.text) 
1504   
1505          root.text = CDATA(_str("test")) 
1506          self.assertEqual('test', root.text) 
1507   
1508          self.assertRaises(TypeError, CDATA, 1) 
1509   
1511          CDATA = self.etree.CDATA 
1512          Element = self.etree.Element 
1513   
1514          root = Element("root") 
1515          cdata = CDATA('test') 
1516   
1517          self.assertRaises(TypeError, 
1518                            root.set, 'attr', cdata) 
1519          self.assertRaises(TypeError, 
1520                            operator.setitem, root.attrib, 'attr', cdata) 
1521   
1523          tostring = self.etree.tostring 
1524          parser = self.etree.XMLParser(strip_cdata=False) 
1525          root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 
1526   
1527          self.assertEqual('test', root.text) 
1528          self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 
1529                            tostring(root)) 
1530   
1532          tostring = self.etree.tostring 
1533          parser = self.etree.XMLParser(strip_cdata=False) 
1534          root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser) 
1535          self.assertEqual(_bytes('<root><![CDATA[test]]></root>'), 
1536                            tostring(root)) 
1537   
1538          self.assertEqual(['test'], root.xpath('//text()')) 
1539   
1540      # TypeError in etree, AssertionError in ElementTree; 
1542          Element = self.etree.Element 
1543          SubElement = self.etree.SubElement 
1544   
1545          a = Element('a') 
1546          b = SubElement(a, 'b') 
1547           
1548          self.assertRaises(TypeError, 
1549                            a.__setitem__, 0, 'foo') 
1550   
1552          Element = self.etree.Element 
1553          root = Element('root') 
1554          # raises AssertionError in ElementTree 
1555          self.assertRaises(TypeError, root.append, None) 
1556          self.assertRaises(TypeError, root.extend, [None]) 
1557          self.assertRaises(TypeError, root.extend, [Element('one'), None]) 
1558          self.assertEqual('one', root[0].tag) 
1559   
1561          Element = self.etree.Element 
1562          SubElement = self.etree.SubElement 
1563          root = Element('root') 
1564          self.assertRaises(ValueError, root.append, root) 
1565          child = SubElement(root, 'child') 
1566          self.assertRaises(ValueError, child.append, root) 
1567          child2 = SubElement(child, 'child2') 
1568          self.assertRaises(ValueError, child2.append, root) 
1569          self.assertRaises(ValueError, child2.append, child) 
1570          self.assertEqual('child2', root[0][0].tag) 
1571   
1573          Element = self.etree.Element 
1574          SubElement = self.etree.SubElement 
1575          root = Element('root') 
1576          SubElement(root, 'a') 
1577          SubElement(root, 'b') 
1578   
1579          self.assertEqual(['a', 'b'], 
1580                            [c.tag for c in root]) 
1581          root[1].addnext(root[0]) 
1582          self.assertEqual(['b', 'a'], 
1583                            [c.tag for c in root]) 
1584   
1586          Element = self.etree.Element 
1587          SubElement = self.etree.SubElement 
1588          root = Element('root') 
1589          SubElement(root, 'a') 
1590          SubElement(root, 'b') 
1591   
1592          self.assertEqual(['a', 'b'], 
1593                            [c.tag for c in root]) 
1594          root[0].addprevious(root[1]) 
1595          self.assertEqual(['b', 'a'], 
1596                            [c.tag for c in root]) 
1597   
1599          Element = self.etree.Element 
1600          SubElement = self.etree.SubElement 
1601          root = Element('root') 
1602          a = SubElement(root, 'a') 
1603          b = SubElement(a, 'b') 
1604          # appending parent as sibling is forbidden 
1605          self.assertRaises(ValueError, b.addnext, a) 
1606          self.assertEqual(['a'], [c.tag for c in root]) 
1607          self.assertEqual(['b'], [c.tag for c in a]) 
1608   
1610          Element = self.etree.Element 
1611          SubElement = self.etree.SubElement 
1612          root = Element('root') 
1613          a = SubElement(root, 'a') 
1614          b = SubElement(a, 'b') 
1615          # appending parent as sibling is forbidden 
1616          self.assertRaises(ValueError, b.addprevious, a) 
1617          self.assertEqual(['a'], [c.tag for c in root]) 
1618          self.assertEqual(['b'], [c.tag for c in a]) 
1619   
1621          Element = self.etree.Element 
1622          SubElement = self.etree.SubElement 
1623          root = Element('root') 
1624          a = SubElement(root, 'a') 
1625          b = SubElement(a, 'b') 
1626          c = SubElement(b, 'c') 
1627          # appending parent as sibling is forbidden 
1628          self.assertRaises(ValueError, c.addnext, a) 
1629   
1631          Element = self.etree.Element 
1632          SubElement = self.etree.SubElement 
1633          root = Element('root') 
1634          a = SubElement(root, 'a') 
1635          b = SubElement(a, 'b') 
1636          c = SubElement(b, 'c') 
1637          # appending parent as sibling is forbidden 
1638          self.assertRaises(ValueError, c.addprevious, a) 
1639   
1641          Element = self.etree.Element 
1642          SubElement = self.etree.SubElement 
1643          root = Element('root') 
1644          a = SubElement(root, 'a') 
1645          b = SubElement(root, 'b') 
1646          a.addprevious(a) 
1647          self.assertEqual('a', root[0].tag) 
1648          self.assertEqual('b', root[1].tag) 
1649          b.addprevious(b) 
1650          self.assertEqual('a', root[0].tag) 
1651          self.assertEqual('b', root[1].tag) 
1652          b.addprevious(a) 
1653          self.assertEqual('a', root[0].tag) 
1654          self.assertEqual('b', root[1].tag) 
1655   
1657          Element = self.etree.Element 
1658          SubElement = self.etree.SubElement 
1659          root = Element('root') 
1660          a = SubElement(root, 'a') 
1661          b = SubElement(root, 'b') 
1662          a.addnext(a) 
1663          self.assertEqual('a', root[0].tag) 
1664          self.assertEqual('b', root[1].tag) 
1665          b.addnext(b) 
1666          self.assertEqual('a', root[0].tag) 
1667          self.assertEqual('b', root[1].tag) 
1668          a.addnext(b) 
1669          self.assertEqual('a', root[0].tag) 
1670          self.assertEqual('b', root[1].tag) 
1671   
1673          Element = self.etree.Element 
1674          a = Element('a') 
1675          b = Element('b') 
1676          self.assertRaises(TypeError, a.addnext, b) 
1677   
1679          Element = self.etree.Element 
1680          SubElement = self.etree.SubElement 
1681          PI = self.etree.PI 
1682          root = Element('root') 
1683          SubElement(root, 'a') 
1684          pi = PI('TARGET', 'TEXT') 
1685          pi.tail = "TAIL" 
1686   
1687          self.assertEqual(_bytes('<root><a></a></root>'), 
1688                            self._writeElement(root)) 
1689          root[0].addprevious(pi) 
1690          self.assertEqual(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'), 
1691                            self._writeElement(root)) 
1692   
1694          Element = self.etree.Element 
1695          PI = self.etree.PI 
1696          root = Element('root') 
1697          pi = PI('TARGET', 'TEXT') 
1698          pi.tail = "TAIL" 
1699   
1700          self.assertEqual(_bytes('<root></root>'), 
1701                            self._writeElement(root)) 
1702          root.addprevious(pi) 
1703          self.assertEqual(_bytes('<?TARGET TEXT?>\n<root></root>'), 
1704                            self._writeElement(root)) 
1705   
1707          Element = self.etree.Element 
1708          SubElement = self.etree.SubElement 
1709          PI = self.etree.PI 
1710          root = Element('root') 
1711          SubElement(root, 'a') 
1712          pi = PI('TARGET', 'TEXT') 
1713          pi.tail = "TAIL" 
1714   
1715          self.assertEqual(_bytes('<root><a></a></root>'), 
1716                            self._writeElement(root)) 
1717          root[0].addnext(pi) 
1718          self.assertEqual(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'), 
1719                            self._writeElement(root)) 
1720   
1722          Element = self.etree.Element 
1723          PI = self.etree.PI 
1724          root = Element('root') 
1725          pi = PI('TARGET', 'TEXT') 
1726          pi.tail = "TAIL" 
1727   
1728          self.assertEqual(_bytes('<root></root>'), 
1729                            self._writeElement(root)) 
1730          root.addnext(pi) 
1731          self.assertEqual(_bytes('<root></root>\n<?TARGET TEXT?>'), 
1732                            self._writeElement(root)) 
1733   
1735          Element = self.etree.Element 
1736          SubElement = self.etree.SubElement 
1737          Comment = self.etree.Comment 
1738          root = Element('root') 
1739          SubElement(root, 'a') 
1740          comment = Comment('TEXT ') 
1741          comment.tail = "TAIL" 
1742   
1743          self.assertEqual(_bytes('<root><a></a></root>'), 
1744                            self._writeElement(root)) 
1745          root[0].addnext(comment) 
1746          self.assertEqual(_bytes('<root><a></a><!--TEXT -->TAIL</root>'), 
1747                            self._writeElement(root)) 
1748   
1750          Element = self.etree.Element 
1751          Comment = self.etree.Comment 
1752          root = Element('root') 
1753          comment = Comment('TEXT ') 
1754          comment.tail = "TAIL" 
1755   
1756          self.assertEqual(_bytes('<root></root>'), 
1757                            self._writeElement(root)) 
1758          root.addnext(comment) 
1759          self.assertEqual(_bytes('<root></root>\n<!--TEXT -->'), 
1760                            self._writeElement(root)) 
1761   
1763          Element = self.etree.Element 
1764          SubElement = self.etree.SubElement 
1765          Comment = self.etree.Comment 
1766          root = Element('root') 
1767          SubElement(root, 'a') 
1768          comment = Comment('TEXT ') 
1769          comment.tail = "TAIL" 
1770   
1771          self.assertEqual(_bytes('<root><a></a></root>'), 
1772                            self._writeElement(root)) 
1773          root[0].addprevious(comment) 
1774          self.assertEqual(_bytes('<root><!--TEXT -->TAIL<a></a></root>'), 
1775                            self._writeElement(root)) 
1776   
1778          Element = self.etree.Element 
1779          Comment = self.etree.Comment 
1780          root = Element('root') 
1781          comment = Comment('TEXT ') 
1782          comment.tail = "TAIL" 
1783   
1784          self.assertEqual(_bytes('<root></root>'), 
1785                            self._writeElement(root)) 
1786          root.addprevious(comment) 
1787          self.assertEqual(_bytes('<!--TEXT -->\n<root></root>'), 
1788                            self._writeElement(root)) 
1789   
1790      # ET's Elements have items() and key(), but not values() 
1792          XML = self.etree.XML 
1793           
1794          root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>')) 
1795          values = root.values() 
1796          values.sort() 
1797          self.assertEqual(['Alpha', 'Beta', 'Gamma'], values) 
1798   
1799      # gives error in ElementTree 
1801          Element = self.etree.Element 
1802          Comment = self.etree.Comment 
1803   
1804          a = Element('a') 
1805          a.append(Comment()) 
1806          self.assertEqual( 
1807              _bytes('<a><!----></a>'), 
1808              self._writeElement(a)) 
1809   
1810      # ElementTree ignores comments 
1812          ElementTree = self.etree.ElementTree 
1813          tostring = self.etree.tostring 
1814   
1815          xml = _bytes('<a><b/><!----><c/></a>') 
1816          f = BytesIO(xml) 
1817          doc = ElementTree(file=f) 
1818          a = doc.getroot() 
1819          self.assertEqual( 
1820              '', 
1821              a[1].text) 
1822          self.assertEqual( 
1823              xml, 
1824              tostring(a)) 
1825   
1826      # ElementTree ignores comments 
1828          ElementTree = self.etree.ElementTree 
1829           
1830          f = BytesIO('<a><b></b><!-- hoi --><c></c></a>') 
1831          doc = ElementTree(file=f) 
1832          a = doc.getroot() 
1833          self.assertEqual( 
1834              ' hoi ', 
1835              a[1].text) 
1836   
1837      # does not raise an exception in ElementTree 
1839          Element = self.etree.Element 
1840          Comment = self.etree.Comment 
1841   
1842          c = Comment() 
1843          el = Element('myel') 
1844   
1845          self.assertRaises(TypeError, c.append, el) 
1846          self.assertRaises(TypeError, c.insert, 0, el) 
1847          self.assertRaises(TypeError, c.set, "myattr", "test") 
1848   
1850          c = self.etree.Comment() 
1851          self.assertEqual(0, len(c.attrib)) 
1852   
1853          self.assertFalse(c.attrib.__contains__('nope')) 
1854          self.assertFalse('nope' in c.attrib) 
1855          self.assertFalse('nope' in c.attrib.keys()) 
1856          self.assertFalse('nope' in c.attrib.values()) 
1857          self.assertFalse(('nope', 'huhu') in c.attrib.items()) 
1858   
1859          self.assertEqual([], list(c.attrib)) 
1860          self.assertEqual([], list(c.attrib.keys())) 
1861          self.assertEqual([], list(c.attrib.items())) 
1862          self.assertEqual([], list(c.attrib.values())) 
1863          self.assertEqual([], list(c.attrib.iterkeys())) 
1864          self.assertEqual([], list(c.attrib.iteritems())) 
1865          self.assertEqual([], list(c.attrib.itervalues())) 
1866   
1867          self.assertEqual('HUHU', c.attrib.pop('nope', 'HUHU')) 
1868          self.assertRaises(KeyError, c.attrib.pop, 'nope') 
1869   
1870          self.assertRaises(KeyError, c.attrib.__getitem__, 'only') 
1871          self.assertRaises(KeyError, c.attrib.__getitem__, 'names') 
1872          self.assertRaises(KeyError, c.attrib.__getitem__, 'nope') 
1873          self.assertRaises(KeyError, c.attrib.__setitem__, 'nope', 'yep') 
1874          self.assertRaises(KeyError, c.attrib.__delitem__, 'nope') 
1875   
1876      # test passing 'None' to dump() 
1879   
1881          ElementTree = self.etree.ElementTree 
1882           
1883          f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>') 
1884          doc = ElementTree(file=f) 
1885          a = doc.getroot() 
1886          self.assertEqual( 
1887              None, 
1888              a.prefix) 
1889          self.assertEqual( 
1890              'foo', 
1891              a[0].prefix) 
1892   
1894          ElementTree = self.etree.ElementTree 
1895           
1896          f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>') 
1897          doc = ElementTree(file=f) 
1898          a = doc.getroot() 
1899          self.assertEqual( 
1900              None, 
1901              a.prefix) 
1902          self.assertEqual( 
1903              None, 
1904              a[0].prefix) 
1905   
1907          Element = self.etree.Element 
1908          SubElement = self.etree.SubElement 
1909   
1910          a = Element('a') 
1911          b = SubElement(a, 'b') 
1912          c = SubElement(a, 'c') 
1913          d = SubElement(b, 'd') 
1914          self.assertEqual( 
1915              None, 
1916              a.getparent()) 
1917          self.assertEqual( 
1918              a, 
1919              b.getparent()) 
1920          self.assertEqual( 
1921              b.getparent(), 
1922              c.getparent()) 
1923          self.assertEqual( 
1924              b, 
1925              d.getparent()) 
1926   
1928          XML = self.etree.XML 
1929           
1930          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 
1931          result = [] 
1932          for el in root.iterchildren(): 
1933              result.append(el.tag) 
1934          self.assertEqual(['one', 'two', 'three'], result) 
1935   
1937          XML = self.etree.XML 
1938           
1939          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>')) 
1940          result = [] 
1941          for el in root.iterchildren(reversed=True): 
1942              result.append(el.tag) 
1943          self.assertEqual(['three', 'two', 'one'], result) 
1944   
1946          XML = self.etree.XML 
1947           
1948          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 
1949          result = [] 
1950          for el in root.iterchildren(tag='two'): 
1951              result.append(el.text) 
1952          self.assertEqual(['Two', 'Bla'], result) 
1953   
1955          XML = self.etree.XML 
1956   
1957          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 
1958          result = [] 
1959          for el in root.iterchildren('two'): 
1960              result.append(el.text) 
1961          self.assertEqual(['Two', 'Bla'], result) 
1962   
1964          XML = self.etree.XML 
1965           
1966          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>')) 
1967          result = [] 
1968          for el in root.iterchildren(reversed=True, tag='two'): 
1969              result.append(el.text) 
1970          self.assertEqual(['Bla', 'Two'], result) 
1971   
1973          XML = self.etree.XML 
1974   
1975          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 
1976          result = [] 
1977          for el in root.iterchildren(tag=['two', 'three']): 
1978              result.append(el.text) 
1979          self.assertEqual(['Two', 'Bla', None], result) 
1980   
1982          XML = self.etree.XML 
1983   
1984          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 
1985          result = [] 
1986          for el in root.iterchildren('two', 'three'): 
1987              result.append(el.text) 
1988          self.assertEqual(['Two', 'Bla', None], result) 
1989   
1991          XML = self.etree.XML 
1992   
1993          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>')) 
1994          result = [] 
1995          for el in root.iterchildren(reversed=True, tag=['two', 'three']): 
1996              result.append(el.text) 
1997          self.assertEqual([None, 'Bla', 'Two'], result) 
1998   
2000          Element    = self.etree.Element 
2001          SubElement = self.etree.SubElement 
2002   
2003          a = Element('a') 
2004          b = SubElement(a, 'b') 
2005          c = SubElement(a, 'c') 
2006          d = SubElement(b, 'd') 
2007          self.assertEqual( 
2008              [], 
2009              list(a.iterancestors())) 
2010          self.assertEqual( 
2011              [a], 
2012              list(b.iterancestors())) 
2013          self.assertEqual( 
2014              [a], 
2015              list(c.iterancestors())) 
2016          self.assertEqual( 
2017              [b, a], 
2018              list(d.iterancestors())) 
2019   
2021          Element    = self.etree.Element 
2022          SubElement = self.etree.SubElement 
2023   
2024          a = Element('a') 
2025          b = SubElement(a, 'b') 
2026          c = SubElement(a, 'c') 
2027          d = SubElement(b, 'd') 
2028          self.assertEqual( 
2029              [a], 
2030              list(d.iterancestors('a'))) 
2031          self.assertEqual( 
2032              [a], 
2033              list(d.iterancestors(tag='a'))) 
2034   
2035          self.assertEqual( 
2036              [b, a], 
2037              list(d.iterancestors('*'))) 
2038          self.assertEqual( 
2039              [b, a], 
2040              list(d.iterancestors(tag='*'))) 
2041   
2043          Element    = self.etree.Element 
2044          SubElement = self.etree.SubElement 
2045   
2046          a = Element('a') 
2047          b = SubElement(a, 'b') 
2048          c = SubElement(a, 'c') 
2049          d = SubElement(b, 'd') 
2050          self.assertEqual( 
2051              [b, a], 
2052              list(d.iterancestors(tag=('a', 'b')))) 
2053          self.assertEqual( 
2054              [b, a], 
2055              list(d.iterancestors('a', 'b'))) 
2056   
2057          self.assertEqual( 
2058              [], 
2059              list(d.iterancestors(tag=('w', 'x', 'y', 'z')))) 
2060          self.assertEqual( 
2061              [], 
2062              list(d.iterancestors('w', 'x', 'y', 'z'))) 
2063   
2064          self.assertEqual( 
2065              [], 
2066              list(d.iterancestors(tag=('d', 'x')))) 
2067          self.assertEqual( 
2068              [], 
2069              list(d.iterancestors('d', 'x'))) 
2070   
2071          self.assertEqual( 
2072              [b, a], 
2073              list(d.iterancestors(tag=('b', '*')))) 
2074          self.assertEqual( 
2075              [b, a], 
2076              list(d.iterancestors('b', '*'))) 
2077   
2078          self.assertEqual( 
2079              [b], 
2080              list(d.iterancestors(tag=('b', 'c')))) 
2081          self.assertEqual( 
2082              [b], 
2083              list(d.iterancestors('b', 'c'))) 
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          e = SubElement(c, 'e') 
2094   
2095          self.assertEqual( 
2096              [b, d, c, e], 
2097              list(a.iterdescendants())) 
2098          self.assertEqual( 
2099              [], 
2100              list(d.iterdescendants())) 
2101   
2103          Element = self.etree.Element 
2104          SubElement = self.etree.SubElement 
2105   
2106          a = Element('a') 
2107          b = SubElement(a, 'b') 
2108          c = SubElement(a, 'c') 
2109          d = SubElement(b, 'd') 
2110          e = SubElement(c, 'e') 
2111   
2112          self.assertEqual( 
2113              [], 
2114              list(a.iterdescendants('a'))) 
2115          self.assertEqual( 
2116              [], 
2117              list(a.iterdescendants(tag='a'))) 
2118   
2119          a2 = SubElement(e, 'a') 
2120          self.assertEqual( 
2121              [a2], 
2122              list(a.iterdescendants('a'))) 
2123   
2124          self.assertEqual( 
2125              [a2], 
2126              list(c.iterdescendants('a'))) 
2127          self.assertEqual( 
2128              [a2], 
2129              list(c.iterdescendants(tag='a'))) 
2130   
2132          Element = self.etree.Element 
2133          SubElement = self.etree.SubElement 
2134   
2135          a = Element('a') 
2136          b = SubElement(a, 'b') 
2137          c = SubElement(a, 'c') 
2138          d = SubElement(b, 'd') 
2139          e = SubElement(c, 'e') 
2140   
2141          self.assertEqual( 
2142              [b, e], 
2143              list(a.iterdescendants(tag=('a', 'b', 'e')))) 
2144          self.assertEqual( 
2145              [b, e], 
2146              list(a.iterdescendants('a', 'b', 'e'))) 
2147   
2148          a2 = SubElement(e, 'a') 
2149          self.assertEqual( 
2150              [b, a2], 
2151              list(a.iterdescendants(tag=('a', 'b')))) 
2152          self.assertEqual( 
2153              [b, a2], 
2154              list(a.iterdescendants('a', 'b'))) 
2155   
2156          self.assertEqual( 
2157              [], 
2158              list(c.iterdescendants(tag=('x', 'y', 'z')))) 
2159          self.assertEqual( 
2160              [], 
2161              list(c.iterdescendants('x', 'y', 'z'))) 
2162   
2163          self.assertEqual( 
2164              [b, d, c, e, a2], 
2165              list(a.iterdescendants(tag=('x', 'y', 'z', '*')))) 
2166          self.assertEqual( 
2167              [b, d, c, e, a2], 
2168              list(a.iterdescendants('x', 'y', 'z', '*'))) 
2169   
2171          Element = self.etree.Element 
2172          SubElement = self.etree.SubElement 
2173   
2174          a = Element('a') 
2175          b = SubElement(a, 'b') 
2176          c = SubElement(a, 'c') 
2177          d = SubElement(b, 'd') 
2178          self.assertEqual( 
2179              a, 
2180              a.getroottree().getroot()) 
2181          self.assertEqual( 
2182              a, 
2183              b.getroottree().getroot()) 
2184          self.assertEqual( 
2185              a, 
2186              d.getroottree().getroot()) 
2187   
2189          Element    = self.etree.Element 
2190          SubElement = self.etree.SubElement 
2191   
2192          a = Element('a') 
2193          b = SubElement(a, 'b') 
2194          c = SubElement(a, 'c') 
2195          self.assertEqual( 
2196              None, 
2197              a.getnext()) 
2198          self.assertEqual( 
2199              c, 
2200              b.getnext()) 
2201          self.assertEqual( 
2202              None, 
2203              c.getnext()) 
2204   
2206          Element    = self.etree.Element 
2207          SubElement = self.etree.SubElement 
2208   
2209          a = Element('a') 
2210          b = SubElement(a, 'b') 
2211          c = SubElement(a, 'c') 
2212          d = SubElement(b, 'd') 
2213          self.assertEqual( 
2214              None, 
2215              a.getprevious()) 
2216          self.assertEqual( 
2217              b, 
2218              c.getprevious()) 
2219          self.assertEqual( 
2220              None, 
2221              b.getprevious()) 
2222   
2224          Element    = self.etree.Element 
2225          SubElement = self.etree.SubElement 
2226   
2227          a = Element('a') 
2228          b = SubElement(a, 'b') 
2229          c = SubElement(a, 'c') 
2230          d = SubElement(b, 'd') 
2231          self.assertEqual( 
2232              [], 
2233              list(a.itersiblings())) 
2234          self.assertEqual( 
2235              [c], 
2236              list(b.itersiblings())) 
2237          self.assertEqual( 
2238              [], 
2239              list(c.itersiblings())) 
2240          self.assertEqual( 
2241              [b], 
2242              list(c.itersiblings(preceding=True))) 
2243          self.assertEqual( 
2244              [], 
2245              list(b.itersiblings(preceding=True))) 
2246   
2248          Element    = self.etree.Element 
2249          SubElement = self.etree.SubElement 
2250   
2251          a = Element('a') 
2252          b = SubElement(a, 'b') 
2253          c = SubElement(a, 'c') 
2254          d = SubElement(b, 'd') 
2255          self.assertEqual( 
2256              [], 
2257              list(a.itersiblings(tag='XXX'))) 
2258          self.assertEqual( 
2259              [c], 
2260              list(b.itersiblings(tag='c'))) 
2261          self.assertEqual( 
2262              [c], 
2263              list(b.itersiblings(tag='*'))) 
2264          self.assertEqual( 
2265              [b], 
2266              list(c.itersiblings(preceding=True, tag='b'))) 
2267          self.assertEqual( 
2268              [], 
2269              list(c.itersiblings(preceding=True, tag='c'))) 
2270   
2272          Element    = self.etree.Element 
2273          SubElement = self.etree.SubElement 
2274   
2275          a = Element('a') 
2276          b = SubElement(a, 'b') 
2277          c = SubElement(a, 'c') 
2278          d = SubElement(b, 'd') 
2279          e = SubElement(a, 'e') 
2280          self.assertEqual( 
2281              [], 
2282              list(a.itersiblings(tag=('XXX', 'YYY')))) 
2283          self.assertEqual( 
2284              [c, e], 
2285              list(b.itersiblings(tag=('c', 'd', 'e')))) 
2286          self.assertEqual( 
2287              [b], 
2288              list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd')))) 
2289          self.assertEqual( 
2290              [c, b], 
2291              list(e.itersiblings(preceding=True, tag=('c', '*')))) 
2292   
2294          parseid = self.etree.parseid 
2295          XML     = self.etree.XML 
2296          xml_text = _bytes(''' 
2297          <!DOCTYPE document [ 
2298          <!ELEMENT document (h1,p)*> 
2299          <!ELEMENT h1 (#PCDATA)> 
2300          <!ATTLIST h1 myid ID #REQUIRED> 
2301          <!ELEMENT p  (#PCDATA)> 
2302          <!ATTLIST p  someid ID #REQUIRED> 
2303          ]> 
2304          <document> 
2305            <h1 myid="chapter1">...</h1> 
2306            <p id="note1" class="note">...</p> 
2307            <p>Regular paragraph.</p> 
2308            <p xml:id="xmlid">XML:ID paragraph.</p> 
2309            <p someid="warn1" class="warning">...</p> 
2310          </document> 
2311          ''') 
2312   
2313          tree, dic = parseid(BytesIO(xml_text)) 
2314          root = tree.getroot() 
2315          root2 = XML(xml_text) 
2316          self.assertEqual(self._writeElement(root), 
2317                            self._writeElement(root2)) 
2318          expected = { 
2319              "chapter1" : root[0], 
2320              "xmlid"    : root[3], 
2321              "warn1"    : root[4] 
2322              } 
2323          self.assertTrue("chapter1" in dic) 
2324          self.assertTrue("warn1" in dic) 
2325          self.assertTrue("xmlid" in dic) 
2326          self._checkIDDict(dic, expected) 
2327   
2329          XMLDTDID = self.etree.XMLDTDID 
2330          XML      = self.etree.XML 
2331          xml_text = _bytes(''' 
2332          <!DOCTYPE document [ 
2333          <!ELEMENT document (h1,p)*> 
2334          <!ELEMENT h1 (#PCDATA)> 
2335          <!ATTLIST h1 myid ID #REQUIRED> 
2336          <!ELEMENT p  (#PCDATA)> 
2337          <!ATTLIST p  someid ID #REQUIRED> 
2338          ]> 
2339          <document> 
2340            <h1 myid="chapter1">...</h1> 
2341            <p id="note1" class="note">...</p> 
2342            <p>Regular paragraph.</p> 
2343            <p xml:id="xmlid">XML:ID paragraph.</p> 
2344            <p someid="warn1" class="warning">...</p> 
2345          </document> 
2346          ''') 
2347   
2348          root, dic = XMLDTDID(xml_text) 
2349          root2 = XML(xml_text) 
2350          self.assertEqual(self._writeElement(root), 
2351                            self._writeElement(root2)) 
2352          expected = { 
2353              "chapter1" : root[0], 
2354              "xmlid"    : root[3], 
2355              "warn1"    : root[4] 
2356              } 
2357          self.assertTrue("chapter1" in dic) 
2358          self.assertTrue("warn1" in dic) 
2359          self.assertTrue("xmlid" in dic) 
2360          self._checkIDDict(dic, expected) 
2361   
2363          XMLDTDID = self.etree.XMLDTDID 
2364          XML      = self.etree.XML 
2365          xml_text = _bytes(''' 
2366          <document> 
2367            <h1 myid="chapter1">...</h1> 
2368            <p id="note1" class="note">...</p> 
2369            <p>Regular paragraph.</p> 
2370            <p someid="warn1" class="warning">...</p> 
2371          </document> 
2372          ''') 
2373   
2374          root, dic = XMLDTDID(xml_text) 
2375          root2 = XML(xml_text) 
2376          self.assertEqual(self._writeElement(root), 
2377                            self._writeElement(root2)) 
2378          expected = {} 
2379          self._checkIDDict(dic, expected) 
2380   
2382          XMLDTDID = self.etree.XMLDTDID 
2383          XML      = self.etree.XML 
2384          xml_text = _bytes(''' 
2385          <!DOCTYPE document [ 
2386          <!ELEMENT document (h1,p)*> 
2387          <!ELEMENT h1 (#PCDATA)> 
2388          <!ATTLIST h1 myid ID #REQUIRED> 
2389          <!ELEMENT p  (#PCDATA)> 
2390          <!ATTLIST p  someid ID #REQUIRED> 
2391          ]> 
2392          <document> 
2393            <h1 myid="chapter1">...</h1> 
2394            <p id="note1" class="note">...</p> 
2395            <p>Regular paragraph.</p> 
2396            <p xml:id="xmlid">XML:ID paragraph.</p> 
2397            <p someid="warn1" class="warning">...</p> 
2398          </document> 
2399          ''') 
2400   
2401          parser = etree.XMLParser(collect_ids=False) 
2402          root, dic = XMLDTDID(xml_text, parser=parser) 
2403          root2 = XML(xml_text) 
2404          self.assertEqual(self._writeElement(root), 
2405                           self._writeElement(root2)) 
2406          self.assertFalse(dic) 
2407          self._checkIDDict(dic, {}) 
2408   
2410          self.assertEqual(len(dic), 
2411                            len(expected)) 
2412          self.assertEqual(sorted(dic.items()), 
2413                            sorted(expected.items())) 
2414          if sys.version_info < (3,): 
2415              self.assertEqual(sorted(dic.iteritems()), 
2416                                sorted(expected.iteritems())) 
2417          self.assertEqual(sorted(dic.keys()), 
2418                            sorted(expected.keys())) 
2419          if sys.version_info < (3,): 
2420              self.assertEqual(sorted(dic.iterkeys()), 
2421                                sorted(expected.iterkeys())) 
2422          if sys.version_info < (3,): 
2423              self.assertEqual(sorted(dic.values()), 
2424                                sorted(expected.values())) 
2425              self.assertEqual(sorted(dic.itervalues()), 
2426                                sorted(expected.itervalues())) 
2427   
2429          etree = self.etree 
2430   
2431          r = {'foo': 'http://ns.infrae.com/foo'} 
2432          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2433          self.assertEqual( 
2434              'foo', 
2435              e.prefix) 
2436          self.assertEqual( 
2437              _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'), 
2438              self._writeElement(e)) 
2439           
2441          etree = self.etree 
2442   
2443          r = {None: 'http://ns.infrae.com/foo'} 
2444          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2445          self.assertEqual( 
2446              None, 
2447              e.prefix) 
2448          self.assertEqual( 
2449              '{http://ns.infrae.com/foo}bar', 
2450              e.tag) 
2451          self.assertEqual( 
2452              _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'), 
2453              self._writeElement(e)) 
2454   
2456          etree = self.etree 
2457   
2458          r = {None: 'http://ns.infrae.com/foo', 'p': 'http://test/'} 
2459          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2460          self.assertEqual(None, e.prefix) 
2461          self.assertEqual('{http://ns.infrae.com/foo}bar', e.tag) 
2462          self.assertEqual( 
2463              _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:p="http://test/"></bar>'), 
2464              self._writeElement(e)) 
2465   
2467          etree = self.etree 
2468   
2469          r = {None: 'http://ns.infrae.com/foo', 
2470               'hoi': 'http://ns.infrae.com/hoi'} 
2471          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2472          e.set('{http://ns.infrae.com/hoi}test', 'value') 
2473          self.assertEqual( 
2474              _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'), 
2475              self._writeElement(e)) 
2476   
2478          etree = self.etree 
2479   
2480          root = etree.Element('{http://test/ns}root', 
2481                               nsmap={None: 'http://test/ns'}) 
2482          sub = etree.Element('{http://test/ns}sub', 
2483                              nsmap={'test': 'http://test/ns'}) 
2484   
2485          sub.attrib['{http://test/ns}attr'] = 'value' 
2486          self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 
2487          self.assertEqual( 
2488              _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 
2489              etree.tostring(sub)) 
2490   
2491          root.append(sub) 
2492          self.assertEqual( 
2493              _bytes('<root xmlns="http://test/ns">' 
2494                     '<sub xmlns:test="http://test/ns" test:attr="value"/>' 
2495                     '</root>'), 
2496              etree.tostring(root)) 
2497   
2499          etree = self.etree 
2500   
2501          root = etree.Element('root') 
2502          sub = etree.Element('{http://test/ns}sub', 
2503                              nsmap={'test': 'http://test/ns'}) 
2504   
2505          sub.attrib['{http://test/ns}attr'] = 'value' 
2506          self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 
2507          self.assertEqual( 
2508              _bytes('<test:sub xmlns:test="http://test/ns" test:attr="value"/>'), 
2509              etree.tostring(sub)) 
2510   
2511          root.append(sub) 
2512          self.assertEqual( 
2513              _bytes('<root>' 
2514                     '<test:sub xmlns:test="http://test/ns" test:attr="value"/>' 
2515                     '</root>'), 
2516              etree.tostring(root)) 
2517   
2519          etree = self.etree 
2520   
2521          root = etree.Element('root') 
2522          sub = etree.Element('{http://test/ns}sub', 
2523                              nsmap={None: 'http://test/ns'}) 
2524   
2525          sub.attrib['{http://test/ns}attr'] = 'value' 
2526          self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 
2527          self.assertEqual( 
2528              _bytes('<sub xmlns="http://test/ns" ' 
2529                     'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 
2530              etree.tostring(sub)) 
2531   
2532          root.append(sub) 
2533          self.assertEqual( 
2534              _bytes('<root>' 
2535                     '<sub xmlns="http://test/ns"' 
2536                     ' xmlns:ns0="http://test/ns" ns0:attr="value"/>' 
2537                     '</root>'), 
2538              etree.tostring(root)) 
2539   
2541          etree = self.etree 
2542   
2543          root = etree.Element('{http://test/ns}root', 
2544                               nsmap={'test': 'http://test/ns', 
2545                                      None: 'http://test/ns'}) 
2546          sub = etree.Element('{http://test/ns}sub', 
2547                              nsmap={None: 'http://test/ns'}) 
2548   
2549          sub.attrib['{http://test/ns}attr'] = 'value' 
2550          self.assertEqual(sub.attrib['{http://test/ns}attr'], 'value') 
2551          self.assertEqual( 
2552              _bytes('<sub xmlns="http://test/ns" ' 
2553                     'xmlns:ns0="http://test/ns" ns0:attr="value"/>'), 
2554              etree.tostring(sub)) 
2555   
2556          root.append(sub) 
2557          self.assertEqual( 
2558              _bytes('<test:root xmlns:test="http://test/ns" xmlns="http://test/ns">' 
2559                     '<test:sub test:attr="value"/>' 
2560                     '</test:root>'), 
2561              etree.tostring(root)) 
2562   
2564          etree = self.etree 
2565          r = {None: 'http://ns.infrae.com/foo', 
2566               'hoi': 'http://ns.infrae.com/hoi'}  
2567          e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r) 
2568          tree = etree.ElementTree(element=e) 
2569          etree.SubElement(e, '{http://ns.infrae.com/hoi}x') 
2570          self.assertEqual( 
2571              _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'), 
2572              self._writeElement(e)) 
2573   
2575          etree = self.etree 
2576   
2577          r = {None: 'http://ns.infrae.com/foo'} 
2578          e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2579          e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2580   
2581          e1.append(e2) 
2582   
2583          self.assertEqual( 
2584              None, 
2585              e1.prefix) 
2586          self.assertEqual( 
2587              None, 
2588              e1[0].prefix) 
2589          self.assertEqual( 
2590              '{http://ns.infrae.com/foo}bar', 
2591              e1.tag) 
2592          self.assertEqual( 
2593              '{http://ns.infrae.com/foo}bar', 
2594              e1[0].tag) 
2595   
2597          etree = self.etree 
2598   
2599          r = {None: 'http://ns.infrae.com/BAR'} 
2600          e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r) 
2601          e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2602   
2603          e1.append(e2) 
2604   
2605          self.assertEqual( 
2606              None, 
2607              e1.prefix) 
2608          self.assertNotEqual( 
2609              None, 
2610              e2.prefix) 
2611          self.assertEqual( 
2612              '{http://ns.infrae.com/BAR}bar', 
2613              e1.tag) 
2614          self.assertEqual( 
2615              '{http://ns.infrae.com/foo}bar', 
2616              e2.tag) 
2617   
2619          ns_href = "http://a.b.c" 
2620          one = self.etree.fromstring( 
2621              _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href)) 
2622          baz = one[0][0] 
2623   
2624          two = self.etree.fromstring( 
2625              _bytes('<root xmlns:ns="%s"/>' % ns_href)) 
2626          two.append(baz) 
2627          del one # make sure the source document is deallocated 
2628   
2629          self.assertEqual('{%s}baz' % ns_href, baz.tag) 
2630          self.assertEqual( 
2631              _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href), 
2632              self.etree.tostring(two)) 
2633   
2635          xml = _bytes( 
2636              '<foo xmlns="F" xmlns:x="x">' 
2637              '<bar xmlns:ns="NS" xmlns:b="b" xmlns="B">' 
2638              '<ns:baz/>' 
2639              '</bar></foo>' 
2640          ) 
2641          root = self.etree.fromstring(xml) 
2642          self.assertEqual(xml, self.etree.tostring(root)) 
2643          self.etree.cleanup_namespaces(root) 
2644          self.assertEqual( 
2645              _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'), 
2646              self.etree.tostring(root)) 
2647   
2649          xml = _bytes( 
2650              '<foo xmlns="F" xmlns:x="X" xmlns:a="A">' 
2651              '<bar xmlns:ns="NS" xmlns:b="b" xmlns="B">' 
2652              '<ns:baz a:test="attr"/>' 
2653              '</bar></foo>' 
2654          ) 
2655          root = self.etree.fromstring(xml) 
2656          self.assertEqual(xml, self.etree.tostring(root)) 
2657          self.etree.cleanup_namespaces(root) 
2658          self.assertEqual( 
2659              _bytes('<foo xmlns="F" xmlns:a="A">' 
2660                     '<bar xmlns:ns="NS" xmlns="B">' 
2661                     '<ns:baz a:test="attr"/>' 
2662                     '</bar></foo>'), 
2663              self.etree.tostring(root)) 
2664   
2666          xml = ('<n12:foo ' + 
2667                 ' '.join('xmlns:n{n}="NS{n}"'.format(n=i) for i in range(100)) + 
2668                 '><n68:a/></n12:foo>').encode('utf8') 
2669          root = self.etree.fromstring(xml) 
2670          self.assertEqual(xml, self.etree.tostring(root)) 
2671          self.etree.cleanup_namespaces(root) 
2672          self.assertEqual( 
2673              b'<n12:foo xmlns:n12="NS12" xmlns:n68="NS68"><n68:a/></n12:foo>', 
2674              self.etree.tostring(root)) 
2675   
2677          xml = ('<root>' + 
2678                 ''.join('<a xmlns:n{n}="NS{n}">'.format(n=i) for i in range(100)) + 
2679                 '<n64:x/>' + '</a>'*100 + '</root>').encode('utf8') 
2680          root = self.etree.fromstring(xml) 
2681          self.assertEqual(xml, self.etree.tostring(root)) 
2682          self.etree.cleanup_namespaces(root) 
2683          self.assertEqual( 
2684              b'<root>' + b'<a>'*64 + b'<a xmlns:n64="NS64">' + b'<a>'*35 + 
2685              b'<n64:x/>' + b'</a>'*100 + b'</root>', 
2686              self.etree.tostring(root)) 
2687   
2689          xml = ('<root>' + 
2690                 ''.join('<a xmlns:n{n}="NS{n}">'.format(n=i) for i in range(100)) + 
2691                 '<n64:x xmlns:a="A" a:attr="X"/>' + 
2692                 '</a>'*100 + 
2693                 '</root>').encode('utf8') 
2694          root = self.etree.fromstring(xml) 
2695          self.assertEqual(xml, self.etree.tostring(root)) 
2696          self.etree.cleanup_namespaces(root, top_nsmap={'n64': 'NS64'}) 
2697          self.assertEqual( 
2698              b'<root xmlns:n64="NS64">' + b'<a>'*100 + 
2699              b'<n64:x xmlns:a="A" a:attr="X"/>' + b'</a>'*100 + b'</root>', 
2700              self.etree.tostring(root)) 
2701   
2703          xml = ('<root xmlns:n64="NS64" xmlns:foo="FOO" xmlns:unused1="UNUSED" xmlns:no="NO">' 
2704                 '<a xmlns:unused2="UNUSED"><n64:x xmlns:a="A" a:attr="X"/></a>' 
2705                 '<foo>foo:bar</foo>' 
2706                 '</root>').encode('utf8') 
2707          root = self.etree.fromstring(xml) 
2708          self.assertEqual(xml, self.etree.tostring(root)) 
2709          self.etree.cleanup_namespaces(root, keep_ns_prefixes=['foo']) 
2710          self.assertEqual( 
2711              b'<root xmlns:n64="NS64" xmlns:foo="FOO">' 
2712              b'<a><n64:x xmlns:a="A" a:attr="X"/></a>' 
2713              b'<foo>foo:bar</foo>' 
2714              b'</root>', 
2715              self.etree.tostring(root)) 
2716   
2718          xml = ('<root xmlns:n64="NS64" xmlns:unused1="UNUSED" xmlns:no="NO">' 
2719                 '<sub xmlns:foo="FOO">' 
2720                 '<a xmlns:unused2="UNUSED"><n64:x xmlns:a="A" a:attr="X"/></a>' 
2721                 '<foo>foo:bar</foo>' 
2722                 '</sub>' 
2723                 '</root>').encode('utf8') 
2724          root = self.etree.fromstring(xml) 
2725          self.assertEqual(xml, self.etree.tostring(root)) 
2726          self.etree.cleanup_namespaces( 
2727              root, 
2728              top_nsmap={'foo': 'FOO', 'unused1': 'UNUSED'}, 
2729              keep_ns_prefixes=['foo']) 
2730          self.assertEqual( 
2731              b'<root xmlns:n64="NS64" xmlns:foo="FOO">' 
2732              b'<sub>' 
2733              b'<a><n64:x xmlns:a="A" a:attr="X"/></a>' 
2734              b'<foo>foo:bar</foo>' 
2735              b'</sub>' 
2736              b'</root>', 
2737              self.etree.tostring(root)) 
2738   
2740          etree = self.etree 
2741   
2742          r = {None: 'http://ns.infrae.com/foo', 
2743               'hoi': 'http://ns.infrae.com/hoi'} 
2744          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r) 
2745          self.assertEqual( 
2746              r, 
2747              e.nsmap) 
2748   
2750          etree = self.etree 
2751   
2752          re = {None: 'http://ns.infrae.com/foo', 
2753               'hoi': 'http://ns.infrae.com/hoi'} 
2754          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re) 
2755   
2756          rs = {None: 'http://ns.infrae.com/honk', 
2757               'top': 'http://ns.infrae.com/top'} 
2758          s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs) 
2759   
2760          r = re.copy() 
2761          r.update(rs) 
2762          self.assertEqual(re, e.nsmap) 
2763          self.assertEqual(r,  s.nsmap) 
2764   
2766          etree = self.etree 
2767          el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description') 
2768          self.assertEqual({'hha': None}, el.nsmap) 
2769   
2771          Element = self.etree.Element 
2772          SubElement = self.etree.SubElement 
2773   
2774          a = Element('a') 
2775          b = SubElement(a, 'b') 
2776          c = SubElement(a, 'c') 
2777          d = SubElement(b, 'd') 
2778          e = SubElement(c, 'e') 
2779          f = SubElement(c, 'f') 
2780   
2781          self.assertEqual( 
2782              [a, b], 
2783                 list(a.getiterator('a', 'b'))) 
2784          self.assertEqual( 
2785              [], 
2786                list(a.getiterator('x', 'y'))) 
2787          self.assertEqual( 
2788              [a, f], 
2789                list(a.getiterator('f', 'a'))) 
2790          self.assertEqual( 
2791              [c, e, f], 
2792                 list(c.getiterator('c', '*', 'a'))) 
2793          self.assertEqual( 
2794              [], 
2795                    list(a.getiterator( (), () ))) 
2796   
2798          Element = self.etree.Element 
2799          SubElement = self.etree.SubElement 
2800   
2801          a = Element('a') 
2802          b = SubElement(a, 'b') 
2803          c = SubElement(a, 'c') 
2804          d = SubElement(b, 'd') 
2805          e = SubElement(c, 'e') 
2806          f = SubElement(c, 'f') 
2807   
2808          self.assertEqual( 
2809              [a, b], 
2810                    list(a.getiterator( ('a', 'b') ))) 
2811          self.assertEqual( 
2812              [], 
2813                list(a.getiterator( ('x', 'y') ))) 
2814          self.assertEqual( 
2815              [a, f], 
2816                    list(a.getiterator( ('f', 'a') ))) 
2817          self.assertEqual( 
2818              [c, e, f], 
2819                       list(c.getiterator( ('c', '*', 'a') ))) 
2820          self.assertEqual( 
2821              [], 
2822                list(a.getiterator( () ))) 
2823   
2825          Element = self.etree.Element 
2826          SubElement = self.etree.SubElement 
2827   
2828          a = Element('{a}a') 
2829          b = SubElement(a, '{a}b') 
2830          c = SubElement(a, '{a}c') 
2831          d = SubElement(b, '{b}d') 
2832          e = SubElement(c, '{a}e') 
2833          f = SubElement(c, '{b}f') 
2834          g = SubElement(c, 'g') 
2835   
2836          self.assertEqual( 
2837              [a], 
2838              list(a.getiterator('{a}a'))) 
2839          self.assertEqual( 
2840              [], 
2841              list(a.getiterator('{b}a'))) 
2842          self.assertEqual( 
2843              [], 
2844              list(a.getiterator('a'))) 
2845          self.assertEqual( 
2846              [a,b,d,c,e,f,g], 
2847              list(a.getiterator('*'))) 
2848          self.assertEqual( 
2849              [f], 
2850              list(c.getiterator('{b}*'))) 
2851          self.assertEqual( 
2852              [d, f], 
2853              list(a.getiterator('{b}*'))) 
2854          self.assertEqual( 
2855              [g], 
2856              list(a.getiterator('g'))) 
2857          self.assertEqual( 
2858              [g], 
2859              list(a.getiterator('{}g'))) 
2860          self.assertEqual( 
2861              [g], 
2862              list(a.getiterator('{}*'))) 
2863   
2865          Element = self.etree.Element 
2866          SubElement = self.etree.SubElement 
2867   
2868          a = Element('{a}a') 
2869          b = SubElement(a, '{nsA}b') 
2870          c = SubElement(b, '{nsB}b') 
2871          d = SubElement(a, 'b') 
2872          e = SubElement(a, '{nsA}e') 
2873          f = SubElement(e, '{nsB}e') 
2874          g = SubElement(e, 'e') 
2875   
2876          self.assertEqual( 
2877              [b, c, d], 
2878              list(a.getiterator('{*}b'))) 
2879          self.assertEqual( 
2880              [e, f, g], 
2881              list(a.getiterator('{*}e'))) 
2882          self.assertEqual( 
2883              [a, b, c, d, e, f, g], 
2884              list(a.getiterator('{*}*'))) 
2885   
2887          Element = self.etree.Element 
2888          Entity = self.etree.Entity 
2889          SubElement = self.etree.SubElement 
2890   
2891          a = Element('a') 
2892          b = SubElement(a, 'b') 
2893          entity_b = Entity("TEST-b") 
2894          b.append(entity_b) 
2895   
2896          self.assertEqual( 
2897              [entity_b], 
2898              list(a.getiterator(Entity))) 
2899   
2900          entity_a = Entity("TEST-a") 
2901          a.append(entity_a) 
2902   
2903          self.assertEqual( 
2904              [entity_b, entity_a], 
2905              list(a.getiterator(Entity))) 
2906   
2907          self.assertEqual( 
2908              [entity_b], 
2909              list(b.getiterator(Entity))) 
2910   
2912          Element = self.etree.Element 
2913          Comment = self.etree.Comment 
2914          PI = self.etree.PI 
2915          SubElement = self.etree.SubElement 
2916   
2917          a = Element('a') 
2918          b = SubElement(a, 'b') 
2919          a.append(Comment("test")) 
2920          a.append(PI("pi", "content")) 
2921          c = SubElement(a, 'c') 
2922   
2923          self.assertEqual( 
2924              [a, b, c], 
2925              list(a.getiterator(Element))) 
2926   
2928          # ElementTree iterates over everything here 
2929          Element = self.etree.Element 
2930          Comment = self.etree.Comment 
2931          PI = self.etree.PI 
2932          SubElement = self.etree.SubElement 
2933   
2934          a = Element('a') 
2935          b = SubElement(a, 'b') 
2936          a.append(Comment("test")) 
2937          a.append(PI("pi", "content")) 
2938          c = SubElement(a, 'c') 
2939   
2940          self.assertEqual( 
2941              [a, b, c], 
2942              list(a.getiterator('*'))) 
2943   
2945          a  = etree.Element("a") 
2946          b  = etree.SubElement(a, "b") 
2947          c  = etree.SubElement(a, "c") 
2948          d1 = etree.SubElement(c, "d") 
2949          d2 = etree.SubElement(c, "d") 
2950          c.text = d1.text = 'TEXT' 
2951   
2952          tree = etree.ElementTree(a) 
2953          self.assertEqual('.', tree.getelementpath(a)) 
2954          self.assertEqual('c/d[1]', tree.getelementpath(d1)) 
2955          self.assertEqual('c/d[2]', tree.getelementpath(d2)) 
2956   
2957          self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 
2958          self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 
2959   
2960          tree = etree.ElementTree(c) 
2961          self.assertEqual('.', tree.getelementpath(c)) 
2962          self.assertEqual('d[2]', tree.getelementpath(d2)) 
2963          self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 
2964   
2965          tree = etree.ElementTree(b)  # not a parent of a/c/d1/d2 
2966          self.assertEqual('.', tree.getelementpath(b)) 
2967          self.assertRaises(ValueError, tree.getelementpath, a) 
2968          self.assertRaises(ValueError, tree.getelementpath, c) 
2969          self.assertRaises(ValueError, tree.getelementpath, d2) 
2970   
2972          a  = etree.Element("{http://ns1/}a") 
2973          b  = etree.SubElement(a, "{http://ns1/}b") 
2974          c  = etree.SubElement(a, "{http://ns1/}c") 
2975          d1 = etree.SubElement(c, "{http://ns1/}d") 
2976          d2 = etree.SubElement(c, "{http://ns2/}d") 
2977          d3 = etree.SubElement(c, "{http://ns1/}d") 
2978   
2979          tree = etree.ElementTree(a) 
2980          self.assertEqual('.', tree.getelementpath(a)) 
2981          self.assertEqual('{http://ns1/}c/{http://ns1/}d[1]', 
2982                           tree.getelementpath(d1)) 
2983          self.assertEqual('{http://ns1/}c/{http://ns2/}d', 
2984                           tree.getelementpath(d2)) 
2985          self.assertEqual('{http://ns1/}c/{http://ns1/}d[2]', 
2986                           tree.getelementpath(d3)) 
2987   
2988          self.assertEqual(a, tree.find(tree.getelementpath(a))) 
2989          self.assertEqual(b, tree.find(tree.getelementpath(b))) 
2990          self.assertEqual(c, tree.find(tree.getelementpath(c))) 
2991          self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 
2992          self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 
2993          self.assertEqual(d3, tree.find(tree.getelementpath(d3))) 
2994   
2995          tree = etree.ElementTree(c) 
2996          self.assertEqual('{http://ns1/}d[1]', tree.getelementpath(d1)) 
2997          self.assertEqual('{http://ns2/}d', tree.getelementpath(d2)) 
2998          self.assertEqual('{http://ns1/}d[2]', tree.getelementpath(d3)) 
2999          self.assertEqual(d1, tree.find(tree.getelementpath(d1))) 
3000          self.assertEqual(d2, tree.find(tree.getelementpath(d2))) 
3001          self.assertEqual(d3, tree.find(tree.getelementpath(d3))) 
3002   
3003          tree = etree.ElementTree(b)  # not a parent of d1/d2 
3004          self.assertRaises(ValueError, tree.getelementpath, d1) 
3005          self.assertRaises(ValueError, tree.getelementpath, d2) 
3006   
3008          XML = self.etree.XML 
3009          ElementTree = self.etree.ElementTree 
3010          QName = self.etree.QName 
3011          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 
3012          self.assertEqual(tree.find(QName("c")), tree.getroot()[2]) 
3013   
3015          XML = self.etree.XML 
3016          ElementTree = self.etree.ElementTree 
3017          QName = self.etree.QName 
3018          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))) 
3019          self.assertEqual(len(list(tree.findall(QName("c")))), 1) 
3020   
3022          XML = self.etree.XML 
3023          ElementTree = self.etree.ElementTree 
3024          QName = self.etree.QName 
3025          tree = ElementTree(XML( 
3026                  _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))) 
3027          self.assertEqual(len(list(tree.findall(QName("b")))), 2) 
3028          self.assertEqual(len(list(tree.findall(QName("X", "b")))), 1) 
3029   
3031          XML = self.etree.XML 
3032          root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')) 
3033          self.assertEqual(len(root.findall(".//{X}b")), 2) 
3034          self.assertEqual(len(root.findall(".//{X}*")), 2) 
3035          self.assertEqual(len(root.findall(".//b")), 3) 
3036   
3038          XML = self.etree.XML 
3039          root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>')) 
3040          nsmap = {'xx': 'X'} 
3041          self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) 
3042          self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 2) 
3043          self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2) 
3044          nsmap = {'xx': 'Y'} 
3045          self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 1) 
3046          self.assertEqual(len(root.findall(".//xx:*", namespaces=nsmap)), 1) 
3047          self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 2) 
3048   
3050          XML = self.etree.XML 
3051          root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><y:b/></a>')) 
3052          nsmap = {'xx': 'X'} 
3053          self.assertEqual(len(root.findall(".//xx:b", namespaces=nsmap)), 2) 
3054          nsmap = {'xx': 'X', None: 'Y'} 
3055          self.assertEqual(len(root.findall(".//b", namespaces=nsmap)), 1) 
3056          nsmap = {'xx': 'X', '': 'Y'} 
3057          self.assertRaises(ValueError, root.findall, ".//xx:b", namespaces=nsmap) 
3058   
3060          XML = self.etree.XML 
3061          root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>')) 
3062          self.assertRaises(SyntaxError, root.findall, '') 
3063          self.assertRaises(SyntaxError, root.findall, '//')  # absolute path on Element 
3064          self.assertRaises(SyntaxError, root.findall, './//') 
3065   
3067          etree = self.etree 
3068          e = etree.Element('foo') 
3069          for i in range(10): 
3070              etree.SubElement(e, 'a%s' % i) 
3071          for i in range(10): 
3072              self.assertEqual( 
3073                  i, 
3074                  e.index(e[i])) 
3075          self.assertEqual( 
3076              3, e.index(e[3], 3)) 
3077          self.assertRaises( 
3078              ValueError, e.index, e[3], 4) 
3079          self.assertRaises( 
3080              ValueError, e.index, e[3], 0, 2) 
3081          self.assertRaises( 
3082              ValueError, e.index, e[8], 0, -3) 
3083          self.assertRaises( 
3084              ValueError, e.index, e[8], -5, -3) 
3085          self.assertEqual( 
3086              8, e.index(e[8], 0, -1)) 
3087          self.assertEqual( 
3088              8, e.index(e[8], -12, -1)) 
3089          self.assertEqual( 
3090              0, e.index(e[0], -12, -1)) 
3091   
3093          etree = self.etree 
3094          e = etree.Element('foo') 
3095          for i in range(10): 
3096              el = etree.SubElement(e, 'a%s' % i) 
3097              el.text = "text%d" % i 
3098              el.tail = "tail%d" % i 
3099   
3100          child0 = e[0] 
3101          child1 = e[1] 
3102          child2 = e[2] 
3103   
3104          e.replace(e[0], e[1]) 
3105          self.assertEqual( 
3106              9, len(e)) 
3107          self.assertEqual( 
3108              child1, e[0]) 
3109          self.assertEqual( 
3110              child1.text, "text1") 
3111          self.assertEqual( 
3112              child1.tail, "tail1") 
3113          self.assertEqual( 
3114              child0.tail, "tail0") 
3115          self.assertEqual( 
3116              child2, e[1]) 
3117   
3118          e.replace(e[-1], e[0]) 
3119          self.assertEqual( 
3120              child1, e[-1]) 
3121          self.assertEqual( 
3122              child1.text, "text1") 
3123          self.assertEqual( 
3124              child1.tail, "tail1") 
3125          self.assertEqual( 
3126              child2, e[0]) 
3127   
3129          etree = self.etree 
3130          e = etree.Element('foo') 
3131          for i in range(10): 
3132              etree.SubElement(e, 'a%s' % i) 
3133   
3134          new_element = etree.Element("test") 
3135          new_element.text = "TESTTEXT" 
3136          new_element.tail = "TESTTAIL" 
3137          child1 = e[1] 
3138          e.replace(e[0], new_element) 
3139          self.assertEqual( 
3140              new_element, e[0]) 
3141          self.assertEqual( 
3142              "TESTTEXT", 
3143              e[0].text) 
3144          self.assertEqual( 
3145              "TESTTAIL", 
3146              e[0].tail) 
3147          self.assertEqual( 
3148              child1, e[1]) 
3149   
3151          Element = self.etree.Element 
3152          SubElement = self.etree.SubElement 
3153   
3154          a = Element('a') 
3155   
3156          e = Element('e') 
3157          f = Element('f') 
3158          g = Element('g') 
3159   
3160          s = [e, f, g] 
3161          a[::-1] = s 
3162          self.assertEqual( 
3163              [g, f, e], 
3164              list(a)) 
3165   
3167          Element = self.etree.Element 
3168          SubElement = self.etree.SubElement 
3169   
3170          a = Element('a') 
3171          b = SubElement(a, 'b') 
3172          c = SubElement(a, 'c') 
3173          d = SubElement(a, 'd') 
3174          e = SubElement(a, 'e') 
3175   
3176          x = Element('x') 
3177          y = Element('y') 
3178   
3179          a[1::2] = [x, y] 
3180          self.assertEqual( 
3181              [b, x, d, y], 
3182              list(a)) 
3183   
3185          Element = self.etree.Element 
3186          SubElement = self.etree.SubElement 
3187   
3188          a = Element('a') 
3189          b = SubElement(a, 'b') 
3190          c = SubElement(a, 'c') 
3191          d = SubElement(a, 'd') 
3192          e = SubElement(a, 'e') 
3193   
3194          x = Element('x') 
3195          y = Element('y') 
3196   
3197          a[1::-1] = [x, y] 
3198          self.assertEqual( 
3199              [y, x, d, e], 
3200              list(a)) 
3201   
3203          Element = self.etree.Element 
3204          SubElement = self.etree.SubElement 
3205   
3206          a = Element('a') 
3207          b = SubElement(a, 'b') 
3208          c = SubElement(a, 'c') 
3209          d = SubElement(a, 'd') 
3210          e = SubElement(a, 'e') 
3211   
3212          x = Element('x') 
3213          y = Element('y') 
3214   
3215          a[::-2] = [x, y] 
3216          self.assertEqual( 
3217              [b, y, d, x], 
3218              list(a)) 
3219   
3221          Element = self.etree.Element 
3222          SubElement = self.etree.SubElement 
3223          try: 
3224              slice 
3225          except NameError: 
3226              print("slice() not found") 
3227              return 
3228   
3229          a = Element('a') 
3230          b = SubElement(a, 'b') 
3231          c = SubElement(a, 'c') 
3232          d = SubElement(a, 'd') 
3233          e = SubElement(a, 'e') 
3234   
3235          x = Element('x') 
3236          y = Element('y') 
3237          z = Element('z') 
3238   
3239          self.assertRaises( 
3240              ValueError, 
3241              operator.setitem, a, slice(1,None,2), [x, y, z]) 
3242   
3243          self.assertEqual( 
3244              [b, c, d, e], 
3245              list(a)) 
3246   
3248          XML = self.etree.XML 
3249          root = XML(_bytes('''<?xml version="1.0"?> 
3250          <root><test> 
3251   
3252          <bla/></test> 
3253          </root> 
3254          ''')) 
3255   
3256          self.assertEqual( 
3257              [2, 2, 4], 
3258              [ el.sourceline for el in root.getiterator() ]) 
3259   
3261          XML = self.etree.XML 
3262          root = XML(_bytes( 
3263              '<?xml version="1.0"?>\n' 
3264              '<root>' + '\n' * 65536 + 
3265              '<p>' + '\n' * 65536 + '</p>\n' + 
3266              '<br/>\n' 
3267              '</root>')) 
3268   
3269          if self.etree.LIBXML_VERSION >= (2, 9): 
3270              expected = [2, 131074, 131076] 
3271          else: 
3272              expected = [2, 65535, 65535] 
3273   
3274          self.assertEqual(expected, [el.sourceline for el in root.iter()]) 
3275   
3277          parse = self.etree.parse 
3278          tree = parse(fileInTestDir('include/test_xinclude.xml')) 
3279   
3280          self.assertEqual( 
3281              [1, 2, 3], 
3282              [ el.sourceline for el in tree.getiterator() ]) 
3283   
3285          iterparse = self.etree.iterparse 
3286          lines = [ el.sourceline for (event, el) in  
3287                    iterparse(fileInTestDir('include/test_xinclude.xml')) ] 
3288   
3289          self.assertEqual( 
3290              [2, 3, 1], 
3291              lines) 
3292   
3294          iterparse = self.etree.iterparse 
3295          lines = [ el.sourceline for (event, el) in  
3296                    iterparse(fileInTestDir('include/test_xinclude.xml'), 
3297                              events=("start",)) ] 
3298   
3299          self.assertEqual( 
3300              [1, 2, 3], 
3301              lines) 
3302   
3304          Element = self.etree.Element 
3305          SubElement = self.etree.SubElement 
3306          el = Element("test") 
3307          self.assertEqual(None, el.sourceline) 
3308   
3309          child = SubElement(el, "test") 
3310          self.assertEqual(None, el.sourceline) 
3311          self.assertEqual(None, child.sourceline) 
3312   
3314          etree = self.etree 
3315          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 
3316          docinfo = root.getroottree().docinfo 
3317          self.assertEqual(docinfo.URL, "http://no/such/url") 
3318   
3320          etree = self.etree 
3321          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 
3322          docinfo = root.getroottree().docinfo 
3323          self.assertEqual(docinfo.URL, "http://no/such/url") 
3324          docinfo.URL = "https://secret/url" 
3325          self.assertEqual(docinfo.URL, "https://secret/url") 
3326   
3328          etree = self.etree 
3329          tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url") 
3330          docinfo = tree.docinfo 
3331          self.assertEqual(docinfo.URL, "http://no/such/url") 
3332   
3334          etree = self.etree 
3335          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 
3336                             base_url="http://no/such/url") 
3337          docinfo = tree.docinfo 
3338          self.assertEqual(docinfo.URL, "http://no/such/url") 
3339   
3341          etree = self.etree 
3342          root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url") 
3343          docinfo = root.getroottree().docinfo 
3344          self.assertEqual(docinfo.URL, "http://no/such/url") 
3345   
3347          etree = self.etree 
3348          xml_header = '<?xml version="1.0" encoding="ascii"?>' 
3349          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 
3350          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 
3351          doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id) 
3352   
3353          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 
3354   
3355          tree = etree.parse(BytesIO(xml)) 
3356          docinfo = tree.docinfo 
3357          self.assertEqual(docinfo.encoding,    "ascii") 
3358          self.assertEqual(docinfo.xml_version, "1.0") 
3359          self.assertEqual(docinfo.public_id,   pub_id) 
3360          self.assertEqual(docinfo.system_url,  sys_id) 
3361          self.assertEqual(docinfo.root_name,   'html') 
3362          self.assertEqual(docinfo.doctype, doctype_string) 
3363   
3365          etree = self.etree 
3366          xml_header = '<?xml version="1.0" encoding="UTF-8"?>' 
3367          sys_id = "some.dtd" 
3368          doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id 
3369          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>') 
3370   
3371          tree = etree.parse(BytesIO(xml)) 
3372          docinfo = tree.docinfo 
3373          self.assertEqual(docinfo.encoding,    "UTF-8") 
3374          self.assertEqual(docinfo.xml_version, "1.0") 
3375          self.assertEqual(docinfo.public_id,   None) 
3376          self.assertEqual(docinfo.system_url,  sys_id) 
3377          self.assertEqual(docinfo.root_name,   'html') 
3378          self.assertEqual(docinfo.doctype, doctype_string) 
3379   
3381          etree = self.etree 
3382          xml = _bytes('<html><body></body></html>') 
3383          tree = etree.parse(BytesIO(xml)) 
3384          docinfo = tree.docinfo 
3385          self.assertEqual(docinfo.encoding,    "UTF-8") 
3386          self.assertEqual(docinfo.xml_version, "1.0") 
3387          self.assertEqual(docinfo.public_id,   None) 
3388          self.assertEqual(docinfo.system_url,  None) 
3389          self.assertEqual(docinfo.root_name,   'html') 
3390          self.assertEqual(docinfo.doctype, '') 
3391   
3393          etree = self.etree 
3394          xml = _bytes('<!DOCTYPE root><root></root>') 
3395          tree = etree.parse(BytesIO(xml)) 
3396          docinfo = tree.docinfo 
3397          self.assertEqual(docinfo.encoding,    "UTF-8") 
3398          self.assertEqual(docinfo.xml_version, "1.0") 
3399          self.assertEqual(docinfo.public_id,   None) 
3400          self.assertEqual(docinfo.system_url,  None) 
3401          self.assertEqual(docinfo.root_name,   'root') 
3402          self.assertEqual(docinfo.doctype, '<!DOCTYPE root>') 
3403   
3405          etree = self.etree 
3406          xml = _bytes('<!DOCTYPE root>\n<root/>') 
3407          tree = etree.parse(BytesIO(xml)) 
3408          self.assertEqual(xml, etree.tostring(tree)) 
3409   
3411          etree = self.etree 
3412          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN" 
3413          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" 
3414          doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)) 
3415   
3416          xml = _bytes('<!DOCTYPE root>\n<root/>') 
3417          tree = etree.parse(BytesIO(xml)) 
3418          self.assertEqual(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string), 
3419                            etree.tostring(tree, doctype=doctype_string)) 
3420   
3422          etree = self.etree 
3423          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 
3424          self.assertEqual(root.base, "http://no/such/url") 
3425          self.assertEqual( 
3426              root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 
3427          root.base = "https://secret/url" 
3428          self.assertEqual(root.base, "https://secret/url") 
3429          self.assertEqual( 
3430              root.get('{http://www.w3.org/XML/1998/namespace}base'), 
3431              "https://secret/url") 
3432   
3434          etree = self.etree 
3435          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url") 
3436          self.assertEqual(root.base, "http://no/such/url") 
3437          self.assertEqual( 
3438              root.get('{http://www.w3.org/XML/1998/namespace}base'), None) 
3439          root.set('{http://www.w3.org/XML/1998/namespace}base', 
3440                   "https://secret/url") 
3441          self.assertEqual(root.base, "https://secret/url") 
3442          self.assertEqual( 
3443              root.get('{http://www.w3.org/XML/1998/namespace}base'), 
3444              "https://secret/url") 
3445   
3447          etree = self.etree 
3448          root = etree.HTML(_bytes("<html><body></body></html>"), 
3449                            base_url="http://no/such/url") 
3450          self.assertEqual(root.base, "http://no/such/url") 
3451   
3453          etree = self.etree 
3454          root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>')) 
3455          self.assertEqual(root.base, "http://no/such/url") 
3456   
3458          # parse from a file object that returns unicode strings 
3459          f = LargeFileLikeUnicode() 
3460          tree = self.etree.parse(f) 
3461          root = tree.getroot() 
3462          self.assertTrue(root.tag.endswith('root')) 
3463   
3465          # check that DTDs that go in also go back out 
3466          xml = _bytes('''\ 
3467          <!DOCTYPE test SYSTEM "test.dtd" [ 
3468            <!ENTITY entity "tasty"> 
3469            <!ELEMENT test (a)> 
3470            <!ELEMENT a (#PCDATA)> 
3471          ]> 
3472          <test><a>test-test</a></test>\ 
3473          ''') 
3474          tree = self.etree.parse(BytesIO(xml)) 
3475          self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")), 
3476                           xml.replace(_bytes(" "), _bytes(""))) 
3477   
3479          Element = self.etree.Element 
3480   
3481          a = Element('a') 
3482          self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho') 
3483          self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho') 
3484   
3485          self.assertRaises(ValueError, Element, 'ha\0ho') 
3486   
3488          Element = self.etree.Element 
3489   
3490          a = Element('a') 
3491          self.assertRaises(ValueError, setattr, a, "text", 
3492                            _str('ha\0ho')) 
3493          self.assertRaises(ValueError, setattr, a, "tail", 
3494                            _str('ha\0ho')) 
3495   
3496          self.assertRaises(ValueError, Element, 
3497                            _str('ha\0ho')) 
3498   
3500          Element = self.etree.Element 
3501   
3502          a = Element('a') 
3503          self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho') 
3504          self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho') 
3505   
3506          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho') 
3507          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho') 
3508   
3509          self.assertRaises(ValueError, Element, 'ha\x07ho') 
3510          self.assertRaises(ValueError, Element, 'ha\x02ho') 
3511   
3513          Element = self.etree.Element 
3514   
3515          a = Element('a') 
3516          self.assertRaises(ValueError, setattr, a, "text", 
3517                            _str('ha\x07ho')) 
3518          self.assertRaises(ValueError, setattr, a, "text", 
3519                            _str('ha\x02ho')) 
3520   
3521          self.assertRaises(ValueError, setattr, a, "tail", 
3522                            _str('ha\x07ho')) 
3523          self.assertRaises(ValueError, setattr, a, "tail", 
3524                            _str('ha\x02ho')) 
3525   
3526          self.assertRaises(ValueError, Element, 
3527                            _str('ha\x07ho')) 
3528          self.assertRaises(ValueError, Element, 
3529                            _str('ha\x02ho')) 
3530   
3532          Element = self.etree.Element 
3533   
3534          a = Element('a') 
3535          self.assertRaises(ValueError, setattr, a, "text", 
3536                            _str('ha\u1234\x07ho')) 
3537          self.assertRaises(ValueError, setattr, a, "text", 
3538                            _str('ha\u1234\x02ho')) 
3539   
3540          self.assertRaises(ValueError, setattr, a, "tail", 
3541                            _str('ha\u1234\x07ho')) 
3542          self.assertRaises(ValueError, setattr, a, "tail", 
3543                            _str('ha\u1234\x02ho')) 
3544   
3545          self.assertRaises(ValueError, Element, 
3546                            _str('ha\u1234\x07ho')) 
3547          self.assertRaises(ValueError, Element, 
3548                            _str('ha\u1234\x02ho')) 
3549   
3551          # ElementTree fails to serialize this 
3552          tostring = self.etree.tostring 
3553          Element = self.etree.Element 
3554          SubElement = self.etree.SubElement 
3555           
3556          a = Element('a') 
3557          b = SubElement(a, 'b') 
3558          c = SubElement(a, 'c') 
3559   
3560          result = tostring(a, encoding='UTF-16') 
3561          self.assertEqual(_bytes('<a><b></b><c></c></a>'), 
3562                            canonicalize(result)) 
3563   
3565          # ElementTree raises an AssertionError here 
3566          tostring = self.etree.tostring 
3567          self.assertRaises(TypeError, self.etree.tostring, None) 
3568   
3570          tostring = self.etree.tostring 
3571          Element = self.etree.Element 
3572          SubElement = self.etree.SubElement 
3573   
3574          a = Element('a') 
3575          b = SubElement(a, 'b') 
3576          c = SubElement(a, 'c') 
3577   
3578          result = tostring(a) 
3579          self.assertEqual(result, _bytes("<a><b/><c/></a>")) 
3580   
3581          result = tostring(a, pretty_print=False) 
3582          self.assertEqual(result, _bytes("<a><b/><c/></a>")) 
3583   
3584          result = tostring(a, pretty_print=True) 
3585          self.assertEqual(result, _bytes("<a>\n  <b/>\n  <c/>\n</a>\n")) 
3586   
3588          tostring = self.etree.tostring 
3589          Element = self.etree.Element 
3590          SubElement = self.etree.SubElement 
3591   
3592          a = Element('a') 
3593          a.tail = "aTAIL" 
3594          b = SubElement(a, 'b') 
3595          b.tail = "bTAIL" 
3596          c = SubElement(a, 'c') 
3597   
3598          result = tostring(a) 
3599          self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL")) 
3600   
3601          result = tostring(a, with_tail=False) 
3602          self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>")) 
3603   
3604          result = tostring(a, with_tail=True) 
3605          self.assertEqual(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL")) 
3606   
3608          tostring = self.etree.tostring 
3609          html = self.etree.fromstring( 
3610              '<html><body>' 
3611              '<div><p>Some text<i>\r\n</i></p></div>\r\n' 
3612              '</body></html>', 
3613              parser=self.etree.HTMLParser()) 
3614          self.assertEqual(html.tag, 'html') 
3615          div = html.find('.//div') 
3616          self.assertEqual(div.tail, '\r\n') 
3617          result = tostring(div, method='html') 
3618          self.assertEqual( 
3619              result, 
3620              _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n")) 
3621          result = tostring(div, method='html', with_tail=True) 
3622          self.assertEqual( 
3623              result, 
3624              _bytes("<div><p>Some text<i>\r\n</i></p></div>\r\n")) 
3625          result = tostring(div, method='html', with_tail=False) 
3626          self.assertEqual( 
3627              result, 
3628              _bytes("<div><p>Some text<i>\r\n</i></p></div>")) 
3629   
3631          tostring = self.etree.tostring 
3632          XML = self.etree.XML 
3633          ElementTree = self.etree.ElementTree 
3634          Element = self.etree.Element 
3635   
3636          tree = Element("root").getroottree() 
3637          self.assertEqual(None, tree.docinfo.standalone) 
3638   
3639          tree = XML(_bytes("<root/>")).getroottree() 
3640          self.assertEqual(None, tree.docinfo.standalone) 
3641   
3642          tree = XML(_bytes( 
3643              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>" 
3644              )).getroottree() 
3645          self.assertEqual(True, tree.docinfo.standalone) 
3646   
3647          tree = XML(_bytes( 
3648              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>" 
3649              )).getroottree() 
3650          self.assertEqual(False, tree.docinfo.standalone) 
3651   
3653          tostring = self.etree.tostring 
3654          XML = self.etree.XML 
3655          ElementTree = self.etree.ElementTree 
3656   
3657          root = XML(_bytes("<root/>")) 
3658   
3659          tree = ElementTree(root) 
3660          self.assertEqual(None, tree.docinfo.standalone) 
3661   
3662          result = tostring(root, xml_declaration=True, encoding="ASCII") 
3663          self.assertEqual(result, _bytes( 
3664              "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 
3665   
3666          result = tostring(root, xml_declaration=True, encoding="ASCII", 
3667                            standalone=True) 
3668          self.assertEqual(result, _bytes( 
3669              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>")) 
3670   
3671          tree = ElementTree(XML(result)) 
3672          self.assertEqual(True, tree.docinfo.standalone) 
3673   
3674          result = tostring(root, xml_declaration=True, encoding="ASCII", 
3675                            standalone=False) 
3676          self.assertEqual(result, _bytes( 
3677              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>")) 
3678   
3679          tree = ElementTree(XML(result)) 
3680          self.assertEqual(False, tree.docinfo.standalone) 
3681   
3683          tostring = self.etree.tostring 
3684          XML = self.etree.XML 
3685          ElementTree = self.etree.ElementTree 
3686   
3687          root = XML(_bytes( 
3688              "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>")) 
3689   
3690          tree = ElementTree(root) 
3691          self.assertEqual(True, tree.docinfo.standalone) 
3692   
3693          result = tostring(root, xml_declaration=True, encoding="ASCII") 
3694          self.assertEqual(result, _bytes( 
3695              "<?xml version='1.0' encoding='ASCII'?>\n<root/>")) 
3696   
3697          result = tostring(root, xml_declaration=True, encoding="ASCII", 
3698                            standalone=True) 
3699          self.assertEqual(result, _bytes( 
3700              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>")) 
3701   
3703          tostring = self.etree.tostring 
3704          Element = self.etree.Element 
3705          SubElement = self.etree.SubElement 
3706           
3707          a = Element('a') 
3708          a.text = "A" 
3709          a.tail = "tail" 
3710          b = SubElement(a, 'b') 
3711          b.text = "B" 
3712          b.tail = _str("Søk på nettet") 
3713          c = SubElement(a, 'c') 
3714          c.text = "C" 
3715   
3716          result = tostring(a, method="text", encoding="UTF-16") 
3717   
3718          self.assertEqual(_str('ABSøk på nettetCtail').encode("UTF-16"), 
3719                            result) 
3720   
3722          tostring = self.etree.tostring 
3723          Element = self.etree.Element 
3724          SubElement = self.etree.SubElement 
3725           
3726          a = Element('a') 
3727          a.text = _str('Søk på nettetA') 
3728          a.tail = "tail" 
3729          b = SubElement(a, 'b') 
3730          b.text = "B" 
3731          b.tail = _str('Søk på nettetB') 
3732          c = SubElement(a, 'c') 
3733          c.text = "C" 
3734           
3735          self.assertRaises(UnicodeEncodeError, 
3736                            tostring, a, method="text") 
3737           
3738          self.assertEqual( 
3739              _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'), 
3740              tostring(a, encoding="UTF-8", method="text")) 
3741   
3743          tounicode = self.etree.tounicode 
3744          Element = self.etree.Element 
3745          SubElement = self.etree.SubElement 
3746           
3747          a = Element('a') 
3748          b = SubElement(a, 'b') 
3749          c = SubElement(a, 'c') 
3750           
3751          self.assertTrue(isinstance(tounicode(a), _unicode)) 
3752          self.assertEqual(_bytes('<a><b></b><c></c></a>'), 
3753                            canonicalize(tounicode(a))) 
3754   
3756          tounicode = self.etree.tounicode 
3757          Element = self.etree.Element 
3758          SubElement = self.etree.SubElement 
3759           
3760          a = Element('a') 
3761          b = SubElement(a, 'b') 
3762          c = SubElement(a, 'c') 
3763          d = SubElement(c, 'd') 
3764          self.assertTrue(isinstance(tounicode(b), _unicode)) 
3765          self.assertTrue(isinstance(tounicode(c), _unicode)) 
3766          self.assertEqual(_bytes('<b></b>'), 
3767                            canonicalize(tounicode(b))) 
3768          self.assertEqual(_bytes('<c><d></d></c>'), 
3769                            canonicalize(tounicode(c))) 
3770   
3774   
3776          tounicode = self.etree.tounicode 
3777          Element = self.etree.Element 
3778          SubElement = self.etree.SubElement 
3779           
3780          a = Element('a') 
3781          b = SubElement(a, 'b') 
3782          c = SubElement(a, 'c') 
3783          d = SubElement(c, 'd') 
3784          b.tail = 'Foo' 
3785   
3786          self.assertTrue(isinstance(tounicode(b), _unicode)) 
3787          self.assertTrue(tounicode(b) == '<b/>Foo' or 
3788                       tounicode(b) == '<b />Foo') 
3789   
3791          tounicode = self.etree.tounicode 
3792          Element = self.etree.Element 
3793          SubElement = self.etree.SubElement 
3794   
3795          a = Element('a') 
3796          b = SubElement(a, 'b') 
3797          c = SubElement(a, 'c') 
3798   
3799          result = tounicode(a) 
3800          self.assertEqual(result, "<a><b/><c/></a>") 
3801   
3802          result = tounicode(a, pretty_print=False) 
3803          self.assertEqual(result, "<a><b/><c/></a>") 
3804   
3805          result = tounicode(a, pretty_print=True) 
3806          self.assertEqual(result, "<a>\n  <b/>\n  <c/>\n</a>\n") 
3807   
3809          tostring = self.etree.tostring 
3810          Element = self.etree.Element 
3811          SubElement = self.etree.SubElement 
3812           
3813          a = Element('a') 
3814          b = SubElement(a, 'b') 
3815          c = SubElement(a, 'c') 
3816           
3817          self.assertTrue(isinstance(tostring(a, encoding=_unicode), _unicode)) 
3818          self.assertEqual(_bytes('<a><b></b><c></c></a>'), 
3819                            canonicalize(tostring(a, encoding=_unicode))) 
3820   
3822          tostring = self.etree.tostring 
3823          Element = self.etree.Element 
3824          SubElement = self.etree.SubElement 
3825           
3826          a = Element('a') 
3827          b = SubElement(a, 'b') 
3828          c = SubElement(a, 'c') 
3829          d = SubElement(c, 'd') 
3830          self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 
3831          self.assertTrue(isinstance(tostring(c, encoding=_unicode), _unicode)) 
3832          self.assertEqual(_bytes('<b></b>'), 
3833                            canonicalize(tostring(b, encoding=_unicode))) 
3834          self.assertEqual(_bytes('<c><d></d></c>'), 
3835                            canonicalize(tostring(c, encoding=_unicode))) 
3836   
3838          tostring = self.etree.tostring 
3839          self.assertRaises(TypeError, self.etree.tostring, 
3840                            None, encoding=_unicode) 
3841   
3843          tostring = self.etree.tostring 
3844          Element = self.etree.Element 
3845          SubElement = self.etree.SubElement 
3846           
3847          a = Element('a') 
3848          b = SubElement(a, 'b') 
3849          c = SubElement(a, 'c') 
3850          d = SubElement(c, 'd') 
3851          b.tail = 'Foo' 
3852   
3853          self.assertTrue(isinstance(tostring(b, encoding=_unicode), _unicode)) 
3854          self.assertTrue(tostring(b, encoding=_unicode) == '<b/>Foo' or 
3855                       tostring(b, encoding=_unicode) == '<b />Foo') 
3856   
3858          tostring = self.etree.tostring 
3859          Element = self.etree.Element 
3860          SubElement = self.etree.SubElement 
3861   
3862          a = Element('a') 
3863          b = SubElement(a, 'b') 
3864          c = SubElement(a, 'c') 
3865   
3866          result = tostring(a, encoding=_unicode) 
3867          self.assertEqual(result, "<a><b/><c/></a>") 
3868   
3869          result = tostring(a, encoding=_unicode, pretty_print=False) 
3870          self.assertEqual(result, "<a><b/><c/></a>") 
3871   
3872          result = tostring(a, encoding=_unicode, pretty_print=True) 
3873          self.assertEqual(result, "<a>\n  <b/>\n  <c/>\n</a>\n") 
3874   
3876          root = etree.Element('parent') 
3877          etree.SubElement(root, 'child') 
3878   
3879          self.assertEqual(len(root), 1) 
3880          self.assertEqual(root[0].tag, 'child') 
3881   
3882          # in PyPy, GC used to kill the Python proxy instance without cleanup 
3883          gc.collect() 
3884          self.assertEqual(len(root), 1) 
3885          self.assertEqual(root[0].tag, 'child') 
3886   
3890   
3891          el1 = SubEl() 
3892          el2 = SubEl() 
3893          self.assertEqual('SubEl', el1.tag) 
3894          self.assertEqual('SubEl', el2.tag) 
3895          el1.other = el2 
3896          el2.other = el1 
3897   
3898          del el1, el2 
3899          gc.collect() 
3900          # not really testing anything here, but it shouldn't crash 
3901   
3903          root = etree.Element('parent') 
3904          c1 = etree.SubElement(root, 'child1') 
3905          c2 = etree.SubElement(root, 'child2') 
3906   
3907          root.remove(c1) 
3908          root.remove(c2) 
3909          c1.addnext(c2) 
3910          del c1 
3911          # trigger deallocation attempt of c1 
3912          c2.getprevious() 
3913          # make sure it wasn't deallocated 
3914          self.assertEqual('child1', c2.getprevious().tag) 
3915   
3917          root = etree.Element('parent') 
3918          c1 = etree.SubElement(root, 'child1') 
3919          c2 = etree.SubElement(root, 'child2') 
3920   
3921          root.remove(c1) 
3922          root.remove(c2) 
3923          c1.addnext(c2) 
3924          c1.tail = 'abc' 
3925          c2.tail = 'xyz' 
3926          del c1 
3927          # trigger deallocation attempt of c1 
3928          c2.getprevious() 
3929          # make sure it wasn't deallocated 
3930          self.assertEqual('child1', c2.getprevious().tag) 
3931          self.assertEqual('abc', c2.getprevious().tail) 
3932   
3933      # helper methods 
3934   
3936          """Write out element for comparison. 
3937          """ 
3938          ElementTree = self.etree.ElementTree 
3939          f = BytesIO() 
3940          tree = ElementTree(element=element) 
3941          tree.write(f, encoding=encoding, compression=compression) 
3942          data = f.getvalue() 
3943          if compression: 
3944              data = zlib.decompress(data) 
3945          return canonicalize(data) 
3946   
3950          filename = fileInTestDir('test_broken.xml') 
3951          root = etree.XML(_bytes('''\ 
3952          <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 
3953            <xi:include href="%s" parse="text"/> 
3954          </doc> 
3955          ''' % path2url(filename))) 
3956          old_text = root.text 
3957          content = read_file(filename) 
3958          old_tail = root[0].tail 
3959   
3960          self.include( etree.ElementTree(root) ) 
3961          self.assertEqual(old_text + content + old_tail, 
3962                            root.text) 
3963   
3965          tree = etree.parse(fileInTestDir('include/test_xinclude.xml')) 
3966          self.assertNotEqual( 
3967              'a', 
3968              tree.getroot()[1].tag) 
3969          # process xincludes 
3970          self.include( tree ) 
3971          # check whether we find it replaced with included data 
3972          self.assertEqual( 
3973              'a', 
3974              tree.getroot()[1].tag) 
3975   
3977          class res(etree.Resolver): 
3978              include_text = read_file(fileInTestDir('test.xml')) 
3979              called = {} 
3980              def resolve(self, url, id, context): 
3981                  if url.endswith(".dtd"): 
3982                      self.called["dtd"] = True 
3983                      return self.resolve_filename( 
3984                          fileInTestDir('test.dtd'), context) 
3985                  elif url.endswith("test_xinclude.xml"): 
3986                      self.called["input"] = True 
3987                      return None # delegate to default resolver 
3988                  else: 
3989                      self.called["include"] = True 
3990                      return self.resolve_string(self.include_text, context) 
3991   
3992          res_instance = res() 
3993          parser = etree.XMLParser(load_dtd = True) 
3994          parser.resolvers.add(res_instance) 
3995   
3996          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 
3997                             parser = parser) 
3998   
3999          self.include(tree) 
4000   
4001          called = list(res_instance.called.items()) 
4002          called.sort() 
4003          self.assertEqual( 
4004              [("dtd", True), ("include", True), ("input", True)], 
4005              called) 
4006   
4008          data = textwrap.dedent(''' 
4009          <doc xmlns:xi="http://www.w3.org/2001/XInclude"> 
4010          <foo/> 
4011          <xi:include href="./test.xml" /> 
4012          </doc> 
4013          ''') 
4014   
4015          class Resolver(etree.Resolver): 
4016              called = {} 
4017   
4018              def resolve(self, url, id, context): 
4019                  if url.endswith("test_xinclude.xml"): 
4020                      assert not self.called.get("input") 
4021                      self.called["input"] = True 
4022                      return None  # delegate to default resolver 
4023                  elif url.endswith('/test5.xml'): 
4024                      assert not self.called.get("DONE") 
4025                      self.called["DONE"] = True 
4026                      return self.resolve_string('<DONE/>', context) 
4027                  else: 
4028                      _, filename = url.rsplit('/', 1) 
4029                      assert not self.called.get(filename) 
4030                      self.called[filename] = True 
4031                      next_data = data.replace( 
4032                          'test.xml', 'test%d.xml' % len(self.called)) 
4033                      return self.resolve_string(next_data, context) 
4034   
4035          res_instance = Resolver() 
4036          parser = etree.XMLParser(load_dtd=True) 
4037          parser.resolvers.add(res_instance) 
4038   
4039          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'), 
4040                             parser=parser) 
4041   
4042          self.include(tree) 
4043   
4044          called = list(res_instance.called.items()) 
4045          called.sort() 
4046          self.assertEqual( 
4047              [("DONE", True), ("input", True), ("test.xml", True), 
4048               ("test2.xml", True), ("test3.xml", True), ("test4.xml", True)], 
4049              called) 
4050   
4055   
4061   
4065          tree = self.parse(_bytes('<a><b/></a>')) 
4066          f = BytesIO() 
4067          tree.write_c14n(f) 
4068          s = f.getvalue() 
4069          self.assertEqual(_bytes('<a><b></b></a>'), 
4070                            s) 
4071   
4073          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4074          f = BytesIO() 
4075          tree.write_c14n(f, compression=9) 
4076          with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile: 
4077              s = gzfile.read() 
4078          self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 
4079                            s) 
4080   
4082          tree = self.parse(_bytes('<a><b/></a>')) 
4083          with tmpfile() as filename: 
4084              tree.write_c14n(filename) 
4085              data = read_file(filename, 'rb') 
4086          self.assertEqual(_bytes('<a><b></b></a>'), 
4087                            data) 
4088   
4090          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4091          with tmpfile() as filename: 
4092              tree.write_c14n(filename, compression=9) 
4093              with closing(gzip.open(filename, 'rb')) as f: 
4094                  data = f.read() 
4095          self.assertEqual(_bytes('<a>'+'<b></b>'*200+'</a>'), 
4096                            data) 
4097   
4099          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 
4100          f = BytesIO() 
4101          tree.write_c14n(f) 
4102          s = f.getvalue() 
4103          self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 
4104                            s) 
4105          f = BytesIO() 
4106          tree.write_c14n(f, with_comments=True) 
4107          s = f.getvalue() 
4108          self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 
4109                            s) 
4110          f = BytesIO() 
4111          tree.write_c14n(f, with_comments=False) 
4112          s = f.getvalue() 
4113          self.assertEqual(_bytes('<a><b></b></a>'), 
4114                            s) 
4115   
4117          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 
4118          s = etree.tostring(tree, method='c14n') 
4119          self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 
4120                            s) 
4121          s = etree.tostring(tree, method='c14n', with_comments=True) 
4122          self.assertEqual(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'), 
4123                            s) 
4124          s = etree.tostring(tree, method='c14n', with_comments=False) 
4125          self.assertEqual(_bytes('<a><b></b></a>'), 
4126                            s) 
4127   
4129          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->')) 
4130          s = etree.tostring(tree.getroot(), method='c14n') 
4131          self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 
4132                            s) 
4133          s = etree.tostring(tree.getroot(), method='c14n', with_comments=True) 
4134          self.assertEqual(_bytes('<a><!--ho--><b></b></a>'), 
4135                            s) 
4136          s = etree.tostring(tree.getroot(), method='c14n', with_comments=False) 
4137          self.assertEqual(_bytes('<a><b></b></a>'), 
4138                            s) 
4139   
4141          tree = self.parse(_bytes( 
4142                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 
4143          f = BytesIO() 
4144          tree.write_c14n(f) 
4145          s = f.getvalue() 
4146          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4147                            s) 
4148          f = BytesIO() 
4149          tree.write_c14n(f, exclusive=False) 
4150          s = f.getvalue() 
4151          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4152                            s) 
4153          f = BytesIO() 
4154          tree.write_c14n(f, exclusive=True) 
4155          s = f.getvalue() 
4156          self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 
4157                            s) 
4158   
4159          f = BytesIO() 
4160          tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z']) 
4161          s = f.getvalue() 
4162          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'), 
4163                            s) 
4164   
4166          tree = self.parse(_bytes( 
4167                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 
4168          s = etree.tostring(tree, method='c14n') 
4169          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4170                            s) 
4171          s = etree.tostring(tree, method='c14n', exclusive=False) 
4172          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4173                            s) 
4174          s = etree.tostring(tree, method='c14n', exclusive=True) 
4175          self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 
4176                            s) 
4177   
4178          s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 
4179          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'), 
4180                            s) 
4181   
4183          tree = self.parse(_bytes( 
4184                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 
4185          s = etree.tostring(tree.getroot(), method='c14n') 
4186          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4187                            s) 
4188          s = etree.tostring(tree.getroot(), method='c14n', exclusive=False) 
4189          self.assertEqual(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4190                            s) 
4191          s = etree.tostring(tree.getroot(), method='c14n', exclusive=True) 
4192          self.assertEqual(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'), 
4193                            s) 
4194   
4195          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False) 
4196          self.assertEqual(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 
4197                            s) 
4198          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True) 
4199          self.assertEqual(_bytes('<z:b xmlns:z="http://cde"></z:b>'), 
4200                            s) 
4201   
4202          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y']) 
4203          self.assertEqual(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'), 
4204                            s) 
4205   
4207          """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)""" 
4208          tree = self.parse(_bytes( 
4209                  '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>')) 
4210   
4211          s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z']) 
4212          self.assertEqual(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'), 
4213                            s) 
4214   
4218          tree = self.parse(_bytes('<a><b/></a>')) 
4219          f = BytesIO() 
4220          tree.write(f) 
4221          s = f.getvalue() 
4222          self.assertEqual(_bytes('<a><b/></a>'), 
4223                            s) 
4224   
4226          tree = self.parse(_bytes('<a><b/></a>')) 
4227          f = BytesIO() 
4228          tree.write(f, doctype='HUHU') 
4229          s = f.getvalue() 
4230          self.assertEqual(_bytes('HUHU\n<a><b/></a>'), 
4231                            s) 
4232   
4234          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4235          f = BytesIO() 
4236          tree.write(f, compression=9) 
4237          with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile: 
4238              s = gzfile.read() 
4239          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4240                            s) 
4241   
4243          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4244          f = BytesIO() 
4245          tree.write(f, compression=9, doctype='<!DOCTYPE a>') 
4246          with closing(gzip.GzipFile(fileobj=BytesIO(f.getvalue()))) as gzfile: 
4247              s = gzfile.read() 
4248          self.assertEqual(_bytes('<!DOCTYPE a>\n<a>'+'<b/>'*200+'</a>'), 
4249                            s) 
4250   
4252          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4253          f = BytesIO() 
4254          tree.write(f, compression=0) 
4255          s0 = f.getvalue() 
4256   
4257          f = BytesIO() 
4258          tree.write(f) 
4259          self.assertEqual(f.getvalue(), s0) 
4260   
4261          f = BytesIO() 
4262          tree.write(f, compression=1) 
4263          s = f.getvalue() 
4264          self.assertTrue(len(s) <= len(s0)) 
4265          with closing(gzip.GzipFile(fileobj=BytesIO(s))) as gzfile: 
4266              s1 = gzfile.read() 
4267   
4268          f = BytesIO() 
4269          tree.write(f, compression=9) 
4270          s = f.getvalue() 
4271          self.assertTrue(len(s) <= len(s0)) 
4272          with closing(gzip.GzipFile(fileobj=BytesIO(s))) as gzfile: 
4273              s9 = gzfile.read() 
4274   
4275          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4276                            s0) 
4277          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4278                            s1) 
4279          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4280                            s9) 
4281   
4283          tree = self.parse(_bytes('<a><b/></a>')) 
4284          with tmpfile() as filename: 
4285              tree.write(filename) 
4286              data = read_file(filename, 'rb') 
4287          self.assertEqual(_bytes('<a><b/></a>'), 
4288                            data) 
4289   
4291          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4292          with tmpfile() as filename: 
4293              tree.write(filename, compression=9) 
4294              with closing(gzip.open(filename, 'rb')) as f: 
4295                  data = f.read() 
4296          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4297                            data) 
4298   
4300          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>')) 
4301          with tmpfile() as filename: 
4302              tree.write(filename, compression=9) 
4303              data = etree.tostring(etree.parse(filename)) 
4304          self.assertEqual(_bytes('<a>'+'<b/>'*200+'</a>'), 
4305                            data) 
4306   
4315   
4318      etree = etree 
4319   
4321          parse = self.etree.parse 
4322          f = BytesIO('<a><b></c></b></a>') 
4323          self.etree.clear_error_log() 
4324          try: 
4325              parse(f) 
4326              logs = None 
4327          except SyntaxError: 
4328              e = sys.exc_info()[1] 
4329              logs = e.error_log 
4330          f.close() 
4331          self.assertTrue([ log for log in logs 
4332                         if 'mismatch' in log.message ]) 
4333          self.assertTrue([ log for log in logs 
4334                         if 'PARSER'   in log.domain_name]) 
4335          self.assertTrue([ log for log in logs 
4336                         if 'ERR_TAG_NAME_MISMATCH' in log.type_name ]) 
4337          self.assertTrue([ log for log in logs 
4338                         if 1 == log.line ]) 
4339          self.assertTrue([ log for log in logs 
4340                         if 15 == log.column ]) 
4341   
4352   
4353          self.etree.use_global_python_log(Logger()) 
4354          f = BytesIO('<a><b></c></b></a>') 
4355          try: 
4356              parse(f) 
4357          except SyntaxError: 
4358              pass 
4359          f.close() 
4360   
4361          self.assertTrue([ message for message in messages 
4362                         if 'mismatch' in message ]) 
4363          self.assertTrue([ message for message in messages 
4364                         if ':PARSER:'   in message]) 
4365          self.assertTrue([ message for message in messages 
4366                         if ':ERR_TAG_NAME_MISMATCH:' in message ]) 
4367          self.assertTrue([ message for message in messages 
4368                         if ':1:15:' in message ]) 
4369   
4384              def close(self): 
4385                  return 'close()' 
4386   
4387          parser = self.etree.XMLPullParser(target=Target()) 
4388          events = parser.read_events() 
4389   
4390          parser.feed('<root><element>') 
4391          self.assertFalse(list(events)) 
4392          self.assertFalse(list(events)) 
4393          parser.feed('</element><child>') 
4394          self.assertEqual([('end', 'end(element)')], list(events)) 
4395          parser.feed('</child>') 
4396          self.assertEqual([('end', 'end(child)')], list(events)) 
4397          parser.feed('</root>') 
4398          self.assertEqual([('end', 'end(root)')], list(events)) 
4399          self.assertFalse(list(events)) 
4400          self.assertEqual('close()', parser.close()) 
4401   
4406              def end(self, tag): 
4407                  return 'end(%s)' % tag 
4408              def close(self): 
4409                  return 'close()' 
4410   
4411          parser = self.etree.XMLPullParser( 
4412              ['start', 'end'], target=Target()) 
4413          events = parser.read_events() 
4414   
4415          parser.feed('<root><element>') 
4416          self.assertEqual( 
4417              [('start', 'start(root)'), ('start', 'start(element)')], 
4418              list(events)) 
4419          self.assertFalse(list(events)) 
4420          parser.feed('</element><child>') 
4421          self.assertEqual( 
4422              [('end', 'end(element)'), ('start', 'start(child)')], 
4423              list(events)) 
4424          parser.feed('</child>') 
4425          self.assertEqual( 
4426              [('end', 'end(child)')], 
4427              list(events)) 
4428          parser.feed('</root>') 
4429          self.assertEqual( 
4430              [('end', 'end(root)')], 
4431              list(events)) 
4432          self.assertFalse(list(events)) 
4433          self.assertEqual('close()', parser.close()) 
4434   
4436          parser = self.etree.XMLPullParser( 
4437              ['start', 'end'], target=etree.TreeBuilder()) 
4438          events = parser.read_events() 
4439   
4440          parser.feed('<root><element>') 
4441          self.assert_event_tags( 
4442              events, [('start', 'root'), ('start', 'element')]) 
4443          self.assertFalse(list(events)) 
4444          parser.feed('</element><child>') 
4445          self.assert_event_tags( 
4446              events, [('end', 'element'), ('start', 'child')]) 
4447          parser.feed('</child>') 
4448          self.assert_event_tags( 
4449              events, [('end', 'child')]) 
4450          parser.feed('</root>') 
4451          self.assert_event_tags( 
4452              events, [('end', 'root')]) 
4453          self.assertFalse(list(events)) 
4454          root = parser.close() 
4455          self.assertEqual('root', root.tag) 
4456   
4458          class Target(etree.TreeBuilder): 
4459              def end(self, tag): 
4460                  el = super(Target, self).end(tag) 
4461                  el.tag += '-huhu' 
4462                  return el 
4463   
4464          parser = self.etree.XMLPullParser( 
4465              ['start', 'end'], target=Target()) 
4466          events = parser.read_events() 
4467   
4468          parser.feed('<root><element>') 
4469          self.assert_event_tags( 
4470              events, [('start', 'root'), ('start', 'element')]) 
4471          self.assertFalse(list(events)) 
4472          parser.feed('</element><child>') 
4473          self.assert_event_tags( 
4474              events, [('end', 'element-huhu'), ('start', 'child')]) 
4475          parser.feed('</child>') 
4476          self.assert_event_tags( 
4477              events, [('end', 'child-huhu')]) 
4478          parser.feed('</root>') 
4479          self.assert_event_tags( 
4480              events, [('end', 'root-huhu')]) 
4481          self.assertFalse(list(events)) 
4482          root = parser.close() 
4483          self.assertEqual('root-huhu', root.tag) 
4484   
4487      suite = unittest.TestSuite() 
4488      suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)]) 
4489      suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)]) 
4490      suite.addTests([unittest.makeSuite(ElementIncludeTestCase)]) 
4491      suite.addTests([unittest.makeSuite(ETreeC14NTestCase)]) 
4492      suite.addTests([unittest.makeSuite(ETreeWriteTestCase)]) 
4493      suite.addTests([unittest.makeSuite(ETreeErrorLogTest)]) 
4494      suite.addTests([unittest.makeSuite(XMLPullParserTest)]) 
4495   
4496      # add original doctests from ElementTree selftest modules 
4497      from . import selftest, selftest2 
4498      suite.addTests(doctest.DocTestSuite(selftest)) 
4499      suite.addTests(doctest.DocTestSuite(selftest2)) 
4500   
4501      # add doctests 
4502      suite.addTests(doctest.DocTestSuite(etree)) 
4503      suite.addTests( 
4504          [make_doctest('../../../doc/tutorial.txt')]) 
4505      if sys.version_info >= (2,6): 
4506          # now requires the 'with' statement 
4507          suite.addTests( 
4508              [make_doctest('../../../doc/api.txt')]) 
4509      suite.addTests( 
4510          [make_doctest('../../../doc/FAQ.txt')]) 
4511      suite.addTests( 
4512          [make_doctest('../../../doc/parsing.txt')]) 
4513      suite.addTests( 
4514          [make_doctest('../../../doc/resolvers.txt')]) 
4515      return suite 
4516   
4517   
4518  if __name__ == '__main__': 
4519      print('to test use test.py %s' % __file__) 
4520   
| Home | Trees | Indices | Help | 
 | 
|---|
| Generated by Epydoc 3.0.1 on Sat Jun 3 17:42:30 2017 | http://epydoc.sourceforge.net |