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