lxml.tests.test_elementtree

Package lxml :: Package tests :: Module test_elementtree |
[hide private]
[frames] | no frames]

# Source Code for Module lxml.tests.test_elementtree

       1  # -*- coding: utf-8 -*-
       2
       3  """
       4  Tests for the ElementTree API
       5
       6  Only test cases that apply equally well to etree and ElementTree
       7  belong here. Note that there is a second test module called test_io.py
       8  for IO related test cases.
       9  """
      10
      11  import unittest
      12  import os, re, tempfile, copy, operator, sys
      13
      14  this_dir = os.path.dirname(__file__)
      15  if this_dir not in sys.path:
      16      sys.path.insert(0, this_dir) # needed for Py3
      17
      18  from common_imports import BytesIO, etree
      19  from common_imports import ElementTree, cElementTree, ET_VERSION, CET_VERSION
      20  from common_imports import filter_by_version, fileInTestDir, canonicalize, HelperTestCase
      21  from common_imports import _str, _bytes, unicode, next
      22
      23  if cElementTree is not None and (CET_VERSION <= (1,0,7) or sys.version_info >= (3,3)):
      24      cElementTree = None
      25
      26  if ElementTree is not None:
      27      print("Comparing with ElementTree %s" % getattr(ElementTree, "VERSION", "?"))
      28
      29  if cElementTree is not None:
      30      print("Comparing with cElementTree %s" % getattr(cElementTree, "VERSION", "?"))
      31
      32 -class _ETreeTestCaseBase(HelperTestCase):
      33      etree = None
      34      required_versions_ET = {}
      35      required_versions_cET = {}
      36
      37 -    def XMLParser(self, **kwargs):
      38          try:
      39              XMLParser = self.etree.XMLParser
      40          except AttributeError:
      41              assert 'ElementTree' in self.etree.__name__
      42              XMLParser = self.etree.TreeBuilder
      43          return XMLParser(**kwargs)
      44
      45 -    def test_element(self):
      46          for i in range(10):
      47              e = self.etree.Element('foo')
      48              self.assertEqual(e.tag, 'foo')
      49              self.assertEqual(e.text, None)
      50              self.assertEqual(e.tail, None)
      51
      52 -    def test_simple(self):
      53          Element = self.etree.Element
      54
      55          root = Element('root')
      56          root.append(Element('one'))
      57          root.append(Element('two'))
      58          root.append(Element('three'))
      59          self.assertEqual(3, len(root))
      60          self.assertEqual('one', root[0].tag)
      61          self.assertEqual('two', root[1].tag)
      62          self.assertEqual('three', root[2].tag)
      63          self.assertRaises(IndexError, operator.getitem, root, 3)
      64
      65      # test weird dictionary interaction leading to segfault previously
      66 -    def test_weird_dict_interaction(self):
      67          root = self.etree.Element('root')
      68          self.assertEqual(root.tag, "root")
      69          add = self.etree.ElementTree(file=BytesIO('<foo>Foo</foo>'))
      70          self.assertEqual(add.getroot().tag, "foo")
      71          self.assertEqual(add.getroot().text, "Foo")
      72          root.append(self.etree.Element('baz'))
      73          self.assertEqual(root.tag, "root")
      74          self.assertEqual(root[0].tag, "baz")
      75
      76 -    def test_subelement(self):
      77          Element = self.etree.Element
      78          SubElement = self.etree.SubElement
      79
      80          root = Element('root')
      81          SubElement(root, 'one')
      82          SubElement(root, 'two')
      83          SubElement(root, 'three')
      84          self.assertEqual(3, len(root))
      85          self.assertEqual('one', root[0].tag)
      86          self.assertEqual('two', root[1].tag)
      87          self.assertEqual('three', root[2].tag)
      88
      89 -    def test_element_contains(self):
      90          Element = self.etree.Element
      91          SubElement = self.etree.SubElement
      92
      93          root1 = Element('root')
      94          SubElement(root1, 'one')
      95          self.assertTrue(root1[0] in root1)
      96
      97          root2 = Element('root')
      98          SubElement(root2, 'two')
      99          SubElement(root2, 'three')
     100          self.assertTrue(root2[0] in root2)
     101          self.assertTrue(root2[1] in root2)
     102
     103          self.assertFalse(root1[0] in root2)
     104          self.assertFalse(root2[0] in root1)
     105          self.assertFalse(None in root2)
     106
     107 -    def test_element_indexing_with_text(self):
     108          ElementTree = self.etree.ElementTree
     109
     110          f = BytesIO('<doc>Test<one>One</one></doc>')
     111          doc = ElementTree(file=f)
     112          root = doc.getroot()
     113          self.assertEqual(1, len(root))
     114          self.assertEqual('one', root[0].tag)
     115          self.assertRaises(IndexError, operator.getitem, root, 1)
     116
     117 -    def test_element_indexing_with_text2(self):
     118          ElementTree = self.etree.ElementTree
     119
     120          f = BytesIO('<doc><one>One</one><two>Two</two>hm<three>Three</three></doc>')
     121          doc = ElementTree(file=f)
     122          root = doc.getroot()
     123          self.assertEqual(3, len(root))
     124          self.assertEqual('one', root[0].tag)
     125          self.assertEqual('two', root[1].tag)
     126          self.assertEqual('three', root[2].tag)
     127
     128 -    def test_element_indexing_only_text(self):
     129          ElementTree = self.etree.ElementTree
     130
     131          f = BytesIO('<doc>Test</doc>')
     132          doc = ElementTree(file=f)
     133          root = doc.getroot()
     134          self.assertEqual(0, len(root))
     135
     136 -    def test_element_indexing_negative(self):
     137          Element = self.etree.Element
     138          SubElement = self.etree.SubElement
     139          a = Element('a')
     140          b = SubElement(a, 'b')
     141          c = SubElement(a, 'c')
     142          d = SubElement(a, 'd')
     143          self.assertEqual(d, a[-1])
     144          self.assertEqual(c, a[-2])
     145          self.assertEqual(b, a[-3])
     146          self.assertRaises(IndexError, operator.getitem, a, -4)
     147          a[-1] = e = Element('e')
     148          self.assertEqual(e, a[-1])
     149          del a[-1]
     150          self.assertEqual(2, len(a))
     151
     152 -    def test_elementtree(self):
     153          ElementTree = self.etree.ElementTree
     154
     155          f = BytesIO('<doc><one>One</one><two>Two</two></doc>')
     156          doc = ElementTree(file=f)
     157          root = doc.getroot()
     158          self.assertEqual(2, len(root))
     159          self.assertEqual('one', root[0].tag)
     160          self.assertEqual('two', root[1].tag)
     161
     162 -    def test_text(self):
     163          ElementTree = self.etree.ElementTree
     164
     165          f = BytesIO('<doc>This is a text</doc>')
     166          doc = ElementTree(file=f)
     167          root = doc.getroot()
     168          self.assertEqual('This is a text', root.text)
     169
     170 -    def test_text_empty(self):
     171          ElementTree = self.etree.ElementTree
     172
     173          f = BytesIO('<doc></doc>')
     174          doc = ElementTree(file=f)
     175          root = doc.getroot()
     176          self.assertEqual(None, root.text)
     177
     178 -    def test_text_other(self):
     179          ElementTree = self.etree.ElementTree
     180
     181          f = BytesIO('<doc><one>One</one></doc>')
     182          doc = ElementTree(file=f)
     183          root = doc.getroot()
     184          self.assertEqual(None, root.text)
     185          self.assertEqual('One', root[0].text)
     186
     187 -    def test_text_escape_in(self):
     188          ElementTree = self.etree.ElementTree
     189
     190          f = BytesIO('<doc>This is &gt; than a text</doc>')
     191          doc = ElementTree(file=f)
     192          root = doc.getroot()
     193          self.assertEqual('This is > than a text', root.text)
     194
     195 -    def test_text_escape_out(self):
     196          Element = self.etree.Element
     197
     198          a = Element("a")
     199          a.text = "<>&"
     200          self.assertXML(_bytes('<a>&lt;&gt;&amp;</a>'),
     201                         a)
     202
     203 -    def test_text_escape_tostring(self):
     204          tostring = self.etree.tostring
     205          Element  = self.etree.Element
     206
     207          a = Element("a")
     208          a.text = "<>&"
     209          self.assertEqual(_bytes('<a>&lt;&gt;&amp;</a>'),
     210                           tostring(a))
     211
     212 -    def test_text_str_subclass(self):
     213          Element = self.etree.Element
     214
     215          class strTest(str):
     216              pass
     217
     218          a = Element("a")
     219          a.text = strTest("text")
     220          self.assertXML(_bytes('<a>text</a>'),
     221                         a)
     222
     223 -    def test_tail(self):
     224          ElementTree = self.etree.ElementTree
     225
     226          f = BytesIO('<doc>This is <i>mixed</i> content.</doc>')
     227          doc = ElementTree(file=f)
     228          root = doc.getroot()
     229          self.assertEqual(1, len(root))
     230          self.assertEqual('This is ', root.text)
     231          self.assertEqual(None, root.tail)
     232          self.assertEqual('mixed', root[0].text)
     233          self.assertEqual(' content.', root[0].tail)
     234
     235 -    def test_tail_str_subclass(self):
     236          Element = self.etree.Element
     237          SubElement = self.etree.SubElement
     238
     239          class strTest(str):
     240              pass
     241
     242          a = Element("a")
     243          SubElement(a, "t").tail = strTest("tail")
     244          self.assertXML(_bytes('<a><t></t>tail</a>'),
     245                         a)
     246
     247 -    def _test_del_tail(self):
     248          # this is discouraged for ET compat, should not be tested...
     249          XML = self.etree.XML
     250
     251          root = XML(_bytes('<doc>This is <i>mixed</i> content.</doc>'))
     252          self.assertEqual(1, len(root))
     253          self.assertEqual('This is ', root.text)
     254          self.assertEqual(None, root.tail)
     255          self.assertEqual('mixed', root[0].text)
     256          self.assertEqual(' content.', root[0].tail)
     257
     258          del root[0].tail
     259
     260          self.assertEqual(1, len(root))
     261          self.assertEqual('This is ', root.text)
     262          self.assertEqual(None, root.tail)
     263          self.assertEqual('mixed', root[0].text)
     264          self.assertEqual(None, root[0].tail)
     265
     266          root[0].tail = "TAIL"
     267
     268          self.assertEqual(1, len(root))
     269          self.assertEqual('This is ', root.text)
     270          self.assertEqual(None, root.tail)
     271          self.assertEqual('mixed', root[0].text)
     272          self.assertEqual('TAIL', root[0].tail)
     273
     274 -    def test_ElementTree(self):
     275          Element = self.etree.Element
     276          ElementTree = self.etree.ElementTree
     277
     278          el = Element('hoi')
     279          doc = ElementTree(el)
     280          root = doc.getroot()
     281          self.assertEqual(None, root.text)
     282          self.assertEqual('hoi', root.tag)
     283
     284 -    def test_attrib(self):
     285          ElementTree = self.etree.ElementTree
     286
     287          f = BytesIO('<doc one="One" two="Two"/>')
     288          doc = ElementTree(file=f)
     289          root = doc.getroot()
     290          self.assertEqual('One', root.attrib['one'])
     291          self.assertEqual('Two', root.attrib['two'])
     292          self.assertRaises(KeyError, operator.getitem, root.attrib, 'three')
     293
     294 -    def test_attrib_get(self):
     295          ElementTree = self.etree.ElementTree
     296
     297          f = BytesIO('<doc one="One" two="Two"/>')
     298          doc = ElementTree(file=f)
     299          root = doc.getroot()
     300          self.assertEqual('One', root.attrib.get('one'))
     301          self.assertEqual('Two', root.attrib.get('two'))
     302          self.assertEqual(None, root.attrib.get('three'))
     303          self.assertEqual('foo', root.attrib.get('three', 'foo'))
     304
     305 -    def test_attrib_dict(self):
     306          ElementTree = self.etree.ElementTree
     307
     308          f = BytesIO('<doc one="One" two="Two"/>')
     309          doc = ElementTree(file=f)
     310          root = doc.getroot()
     311          attrib = dict(root.attrib)
     312          self.assertEqual('One', attrib['one'])
     313          self.assertEqual('Two', attrib['two'])
     314          self.assertRaises(KeyError, operator.getitem, attrib, 'three')
     315
     316 -    def test_attrib_copy(self):
     317          ElementTree = self.etree.ElementTree
     318
     319          f = BytesIO('<doc one="One" two="Two"/>')
     320          doc = ElementTree(file=f)
     321          root = doc.getroot()
     322          attrib = copy.copy(root.attrib)
     323          self.assertEqual('One', attrib['one'])
     324          self.assertEqual('Two', attrib['two'])
     325          self.assertRaises(KeyError, operator.getitem, attrib, 'three')
     326
     327 -    def test_attrib_deepcopy(self):
     328          ElementTree = self.etree.ElementTree
     329
     330          f = BytesIO('<doc one="One" two="Two"/>')
     331          doc = ElementTree(file=f)
     332          root = doc.getroot()
     333          attrib = copy.deepcopy(root.attrib)
     334          self.assertEqual('One', attrib['one'])
     335          self.assertEqual('Two', attrib['two'])
     336          self.assertRaises(KeyError, operator.getitem, attrib, 'three')
     337
     338 -    def test_attributes_get(self):
     339          ElementTree = self.etree.ElementTree
     340
     341          f = BytesIO('<doc one="One" two="Two"/>')
     342          doc = ElementTree(file=f)
     343          root = doc.getroot()
     344          self.assertEqual('One', root.get('one'))
     345          self.assertEqual('Two', root.get('two'))
     346          self.assertEqual(None, root.get('three'))
     347          self.assertEqual('foo', root.get('three', 'foo'))
     348
     349 -    def test_attrib_clear(self):
     350          XML = self.etree.XML
     351
     352          root = XML(_bytes('<doc one="One" two="Two"/>'))
     353          self.assertEqual('One', root.get('one'))
     354          self.assertEqual('Two', root.get('two'))
     355          root.attrib.clear()
     356          self.assertEqual(None, root.get('one'))
     357          self.assertEqual(None, root.get('two'))
     358
     359 -    def test_attrib_set_clear(self):
     360          Element = self.etree.Element
     361
     362          root = Element("root", one="One")
     363          root.set("two", "Two")
     364          self.assertEqual('One', root.get('one'))
     365          self.assertEqual('Two', root.get('two'))
     366          root.attrib.clear()
     367          self.assertEqual(None, root.get('one'))
     368          self.assertEqual(None, root.get('two'))
     369
     370 -    def test_attrib_ns_clear(self):
     371          Element = self.etree.Element
     372          SubElement = self.etree.SubElement
     373
     374          attribNS = '{http://foo/bar}x'
     375
     376          parent = Element('parent')
     377          parent.set(attribNS, 'a')
     378          child = SubElement(parent, 'child')
     379          child.set(attribNS, 'b')
     380
     381          self.assertEqual('a', parent.get(attribNS))
     382          self.assertEqual('b', child.get(attribNS))
     383
     384          parent.clear()
     385          self.assertEqual(None, parent.get(attribNS))
     386          self.assertEqual('b', child.get(attribNS))
     387
     388 -    def test_attrib_pop(self):
     389          ElementTree = self.etree.ElementTree
     390
     391          f = BytesIO('<doc one="One" two="Two"/>')
     392          doc = ElementTree(file=f)
     393          root = doc.getroot()
     394          self.assertEqual('One', root.attrib['one'])
     395          self.assertEqual('Two', root.attrib['two'])
     396
     397          self.assertEqual('One', root.attrib.pop('one'))
     398
     399          self.assertEqual(None, root.attrib.get('one'))
     400          self.assertEqual('Two', root.attrib['two'])
     401
     402 -    def test_attrib_pop_unknown(self):
     403          root = self.etree.XML(_bytes('<doc one="One" two="Two"/>'))
     404          self.assertRaises(KeyError, root.attrib.pop, 'NONE')
     405
     406          self.assertEqual('One', root.attrib['one'])
     407          self.assertEqual('Two', root.attrib['two'])
     408
     409 -    def test_attrib_pop_default(self):
     410          root = self.etree.XML(_bytes('<doc one="One" two="Two"/>'))
     411          self.assertEqual('Three', root.attrib.pop('three', 'Three'))
     412
     413 -    def test_attrib_pop_empty_default(self):
     414          root = self.etree.XML(_bytes('<doc/>'))
     415          self.assertEqual('Three', root.attrib.pop('three', 'Three'))
     416
     417 -    def test_attrib_pop_invalid_args(self):
     418          root = self.etree.XML(_bytes('<doc one="One" two="Two"/>'))
     419          self.assertRaises(TypeError, root.attrib.pop, 'One', None, None)
     420
     421 -    def test_attribute_update_dict(self):
     422          XML = self.etree.XML
     423
     424          root = XML(_bytes('<doc alpha="Alpha" beta="Beta"/>'))
     425          items = list(root.attrib.items())
     426          items.sort()
     427          self.assertEqual(
     428              [('alpha', 'Alpha'), ('beta', 'Beta')],
     429              items)
     430
     431          root.attrib.update({'alpha' : 'test', 'gamma' : 'Gamma'})
     432
     433          items = list(root.attrib.items())
     434          items.sort()
     435          self.assertEqual(
     436              [('alpha', 'test'), ('beta', 'Beta'), ('gamma', 'Gamma')],
     437              items)
     438
     439 -    def test_attribute_update_sequence(self):
     440          XML = self.etree.XML
     441
     442          root = XML(_bytes('<doc alpha="Alpha" beta="Beta"/>'))
     443          items = list(root.attrib.items())
     444          items.sort()
     445          self.assertEqual(
     446              [('alpha', 'Alpha'), ('beta', 'Beta')],
     447              items)
     448
     449          root.attrib.update({'alpha' : 'test', 'gamma' : 'Gamma'}.items())
     450
     451          items = list(root.attrib.items())
     452          items.sort()
     453          self.assertEqual(
     454              [('alpha', 'test'), ('beta', 'Beta'), ('gamma', 'Gamma')],
     455              items)
     456
     457 -    def test_attribute_update_iter(self):
     458          XML = self.etree.XML
     459
     460          root = XML(_bytes('<doc alpha="Alpha" beta="Beta"/>'))
     461          items = list(root.attrib.items())
     462          items.sort()
     463          self.assertEqual(
     464              [('alpha', 'Alpha'), ('beta', 'Beta')],
     465              items)
     466
     467          root.attrib.update(iter({'alpha' : 'test', 'gamma' : 'Gamma'}.items()))
     468
     469          items = list(root.attrib.items())
     470          items.sort()
     471          self.assertEqual(
     472              [('alpha', 'test'), ('beta', 'Beta'), ('gamma', 'Gamma')],
     473              items)
     474
     475 -    def test_attribute_update_attrib(self):
     476          XML = self.etree.XML
     477
     478          root = XML(_bytes('<doc alpha="Alpha" beta="Beta"/>'))
     479          items = list(root.attrib.items())
     480          items.sort()
     481          self.assertEqual(
     482              [('alpha', 'Alpha'), ('beta', 'Beta')],
     483                                                    items)
     484
     485          other = XML(_bytes('<doc alpha="test" gamma="Gamma"/>'))
     486          root.attrib.update(other.attrib)
     487
     488          items = list(root.attrib.items())
     489          items.sort()
     490          self.assertEqual(
     491              [('alpha', 'test'), ('beta', 'Beta'), ('gamma', 'Gamma')],
     492                                                                       items)
     493
     494 -    def test_attribute_keys(self):
     495          XML = self.etree.XML
     496
     497          root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
     498          keys = list(root.attrib.keys())
     499          keys.sort()
     500          self.assertEqual(['alpha', 'beta', 'gamma'], keys)
     501
     502 -    def test_attribute_keys2(self):
     503          XML = self.etree.XML
     504
     505          root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
     506          keys = list(root.keys())
     507          keys.sort()
     508          self.assertEqual(['alpha', 'beta', 'gamma'], keys)
     509
     510 -    def test_attribute_items2(self):
     511          XML = self.etree.XML
     512
     513          root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
     514          items = list(root.items())
     515          items.sort()
     516          self.assertEqual(
     517              [('alpha','Alpha'), ('beta','Beta'), ('gamma','Gamma')],
     518              items)
     519
     520 -    def test_attribute_keys_ns(self):
     521          XML = self.etree.XML
     522
     523          root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
     524          keys = list(root.keys())
     525          keys.sort()
     526          self.assertEqual(['bar', '{http://ns.codespeak.net/test}baz'],
     527                            keys)
     528
     529 -    def test_attribute_values(self):
     530          XML = self.etree.XML
     531
     532          root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
     533          values = list(root.attrib.values())
     534          values.sort()
     535          self.assertEqual(['Alpha', 'Beta', 'Gamma'], values)
     536
     537 -    def test_attribute_values_ns(self):
     538          XML = self.etree.XML
     539
     540          root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
     541          values = list(root.attrib.values())
     542          values.sort()
     543          self.assertEqual(
     544              ['Bar', 'Baz'], values)
     545
     546 -    def test_attribute_items(self):
     547          XML = self.etree.XML
     548
     549          root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
     550          items = list(root.attrib.items())
     551          items.sort()
     552          self.assertEqual([
     553              ('alpha', 'Alpha'),
     554              ('beta', 'Beta'),
     555              ('gamma', 'Gamma'),
     556              ],
     557              items)
     558
     559 -    def test_attribute_items_ns(self):
     560          XML = self.etree.XML
     561
     562          root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
     563          items = list(root.attrib.items())
     564          items.sort()
     565          self.assertEqual(
     566              [('bar', 'Bar'), ('{http://ns.codespeak.net/test}baz', 'Baz')],
     567              items)
     568
     569 -    def test_attribute_str(self):
     570          XML = self.etree.XML
     571
     572          expected = "{'{http://ns.codespeak.net/test}baz': 'Baz', 'bar': 'Bar'}"
     573          alternative = "{'bar': 'Bar', '{http://ns.codespeak.net/test}baz': 'Baz'}"
     574
     575          root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
     576          try:
     577              self.assertEqual(expected, str(root.attrib))
     578          except AssertionError:
     579              self.assertEqual(alternative, str(root.attrib))
     580
     581 -    def test_attribute_contains(self):
     582          XML = self.etree.XML
     583
     584          root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
     585          self.assertEqual(
     586              True, 'bar' in root.attrib)
     587          self.assertEqual(
     588              False, 'baz' in root.attrib)
     589          self.assertEqual(
     590              False, 'hah' in root.attrib)
     591          self.assertEqual(
     592              True,
     593              '{http://ns.codespeak.net/test}baz' in root.attrib)
     594
     595 -    def test_attribute_set(self):
     596          Element = self.etree.Element
     597
     598          root = Element("root")
     599          root.set("attr", "TEST")
     600          self.assertEqual("TEST", root.get("attr"))
     601
     602 -    def test_attrib_as_attrib(self):
     603          Element = self.etree.Element
     604
     605          root = Element("root")
     606          root.set("attr", "TEST")
     607          self.assertEqual("TEST", root.attrib["attr"])
     608
     609          root2 = Element("root2", root.attrib)
     610          self.assertEqual("TEST", root2.attrib["attr"])
     611
     612 -    def test_attribute_iterator(self):
     613          XML = self.etree.XML
     614
     615          root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma" />'))
     616          result = []
     617          for key in root.attrib:
     618              result.append(key)
     619          result.sort()
     620          self.assertEqual(['alpha', 'beta', 'gamma'], result)
     621
     622 -    def test_attribute_manipulation(self):
     623          Element = self.etree.Element
     624
     625          a = Element('a')
     626          a.attrib['foo'] = 'Foo'
     627          a.attrib['bar'] = 'Bar'
     628          self.assertEqual('Foo', a.attrib['foo'])
     629          del a.attrib['foo']
     630          self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
     631
     632 -    def test_del_attribute_ns(self):
     633          Element = self.etree.Element
     634
     635          a = Element('a')
     636          a.attrib['{http://a/}foo'] = 'Foo'
     637          a.attrib['{http://a/}bar'] = 'Bar'
     638          self.assertEqual(None, a.get('foo'))
     639          self.assertEqual('Foo', a.get('{http://a/}foo'))
     640          self.assertEqual('Foo', a.attrib['{http://a/}foo'])
     641
     642          self.assertRaises(KeyError, operator.delitem, a.attrib, 'foo')
     643          self.assertEqual('Foo', a.attrib['{http://a/}foo'])
     644
     645          del a.attrib['{http://a/}foo']
     646          self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
     647
     648 -    def test_del_attribute_ns_parsed(self):
     649          XML = self.etree.XML
     650
     651          a = XML(_bytes('<a xmlns:nsa="http://a/" nsa:foo="FooNS" foo="Foo" />'))
     652
     653          self.assertEqual('Foo', a.attrib['foo'])
     654          self.assertEqual('FooNS', a.attrib['{http://a/}foo'])
     655
     656          del a.attrib['foo']
     657          self.assertEqual('FooNS', a.attrib['{http://a/}foo'])
     658          self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
     659          self.assertRaises(KeyError, operator.delitem, a.attrib, 'foo')
     660
     661          del a.attrib['{http://a/}foo']
     662          self.assertRaises(KeyError, operator.getitem, a.attrib, '{http://a/}foo')
     663          self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
     664
     665          a = XML(_bytes('<a xmlns:nsa="http://a/" foo="Foo" nsa:foo="FooNS" />'))
     666
     667          self.assertEqual('Foo', a.attrib['foo'])
     668          self.assertEqual('FooNS', a.attrib['{http://a/}foo'])
     669
     670          del a.attrib['foo']
     671          self.assertEqual('FooNS', a.attrib['{http://a/}foo'])
     672          self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
     673
     674          del a.attrib['{http://a/}foo']
     675          self.assertRaises(KeyError, operator.getitem, a.attrib, '{http://a/}foo')
     676          self.assertRaises(KeyError, operator.getitem, a.attrib, 'foo')
     677
     678 -    def test_XML(self):
     679          XML = self.etree.XML
     680
     681          root = XML(_bytes('<doc>This is a text.</doc>'))
     682          self.assertEqual(0, len(root))
     683          self.assertEqual('This is a text.', root.text)
     684
     685 -    def test_XMLID(self):
     686          XMLID = self.etree.XMLID
     687          XML   = self.etree.XML
     688          xml_text = _bytes('''
     689          <document>
     690            <h1 id="chapter1">...</h1>
     691            <p id="note1" class="note">...</p>
     692            <p>Regular paragraph.</p>
     693            <p xml:id="xmlid">XML:ID paragraph.</p>
     694            <p id="warn1" class="warning">...</p>
     695          </document>
     696          ''')
     697
     698          root, dic = XMLID(xml_text)
     699          root2 = XML(xml_text)
     700          self.assertEqual(self._writeElement(root),
     701                            self._writeElement(root2))
     702          expected = {
     703              "chapter1" : root[0],
     704              "note1"    : root[1],
     705              "warn1"    : root[4]
     706              }
     707          self.assertEqual(dic, expected)
     708
     709 -    def test_fromstring(self):
     710          fromstring = self.etree.fromstring
     711
     712          root = fromstring('<doc>This is a text.</doc>')
     713          self.assertEqual(0, len(root))
     714          self.assertEqual('This is a text.', root.text)
     715
     716      required_versions_ET['test_fromstringlist'] = (1,3)
     717 -    def test_fromstringlist(self):
     718          fromstringlist = self.etree.fromstringlist
     719
     720          root = fromstringlist(["<do", "c>T", "hi", "s is",
     721                                 " a text.<", "/doc", ">"])
     722          self.assertEqual(0, len(root))
     723          self.assertEqual('This is a text.', root.text)
     724
     725      required_versions_ET['test_fromstringlist_characters'] = (1,3)
     726 -    def test_fromstringlist_characters(self):
     727          fromstringlist = self.etree.fromstringlist
     728
     729          root = fromstringlist(list('<doc>This is a text.</doc>'))
     730          self.assertEqual(0, len(root))
     731          self.assertEqual('This is a text.', root.text)
     732
     733      required_versions_ET['test_fromstringlist_single'] = (1,3)
     734 -    def test_fromstringlist_single(self):
     735          fromstringlist = self.etree.fromstringlist
     736
     737          root = fromstringlist(['<doc>This is a text.</doc>'])
     738          self.assertEqual(0, len(root))
     739          self.assertEqual('This is a text.', root.text)
     740
     741 -    def test_iselement(self):
     742          iselement = self.etree.iselement
     743          Element = self.etree.Element
     744          ElementTree = self.etree.ElementTree
     745          XML = self.etree.XML
     746          Comment = self.etree.Comment
     747          ProcessingInstruction = self.etree.ProcessingInstruction
     748
     749          el = Element('hoi')
     750          self.assertTrue(iselement(el))
     751
     752          el2 = XML(_bytes('<foo/>'))
     753          self.assertTrue(iselement(el2))
     754
     755          tree = ElementTree(element=Element('dag'))
     756          self.assertTrue(not iselement(tree))
     757          self.assertTrue(iselement(tree.getroot()))
     758
     759          c = Comment('test')
     760          self.assertTrue(iselement(c))
     761
     762          p = ProcessingInstruction("test", "some text")
     763          self.assertTrue(iselement(p))
     764
     765 -    def test_iteration(self):
     766          XML = self.etree.XML
     767
     768          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
     769          result = []
     770          for el in root:
     771              result.append(el.tag)
     772          self.assertEqual(['one', 'two', 'three'], result)
     773
     774 -    def test_iteration_empty(self):
     775          XML = self.etree.XML
     776
     777          root = XML(_bytes('<doc></doc>'))
     778          result = []
     779          for el in root:
     780              result.append(el.tag)
     781          self.assertEqual([], result)
     782
     783 -    def test_iteration_text_only(self):
     784          XML = self.etree.XML
     785
     786          root = XML(_bytes('<doc>Text</doc>'))
     787          result = []
     788          for el in root:
     789              result.append(el.tag)
     790          self.assertEqual([], result)
     791
     792 -    def test_iteration_crash(self):
     793          # this would cause a crash in the past
     794          fromstring = self.etree.fromstring
     795          root = etree.fromstring('<html><p></p>x</html>')
     796          for elem in root:
     797              elem.tail = ''
     798
     799 -    def test_iteration_reversed(self):
     800          XML = self.etree.XML
     801          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
     802          result = []
     803          for el in reversed(root):
     804              result.append(el.tag)
     805          self.assertEqual(['three', 'two', 'one'], result)
     806
     807 -    def test_iteration_subelement(self):
     808          XML = self.etree.XML
     809
     810          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
     811          result = []
     812          add = True
     813          for el in root:
     814              result.append(el.tag)
     815              if add:
     816                  self.etree.SubElement(root, 'four')
     817                  add = False
     818          self.assertEqual(['one', 'two', 'three', 'four'], result)
     819
     820 -    def test_iteration_del_child(self):
     821          XML = self.etree.XML
     822
     823          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
     824          result = []
     825          for el in root:
     826              result.append(el.tag)
     827              del root[-1]
     828          self.assertEqual(['one', 'two'], result)
     829
     830 -    def test_iteration_double(self):
     831          XML = self.etree.XML
     832
     833          root = XML(_bytes('<doc><one/><two/></doc>'))
     834          result = []
     835          for el0 in root:
     836              result.append(el0.tag)
     837              for el1 in root:
     838                  result.append(el1.tag)
     839          self.assertEqual(['one','one', 'two', 'two', 'one', 'two'], result)
     840
     841      required_versions_ET['test_itertext'] = (1,3)
     842 -    def test_itertext(self):
     843          # ET 1.3+
     844          XML = self.etree.XML
     845          root = XML(_bytes("<root>RTEXT<a></a>ATAIL<b/><c>CTEXT</c>CTAIL</root>"))
     846
     847          text = list(root.itertext())
     848          self.assertEqual(["RTEXT", "ATAIL", "CTEXT", "CTAIL"],
     849                            text)
     850
     851      required_versions_ET['test_itertext_child'] = (1,3)
     852 -    def test_itertext_child(self):
     853          # ET 1.3+
     854          XML = self.etree.XML
     855          root = XML(_bytes("<root>RTEXT<a></a>ATAIL<b/><c>CTEXT</c>CTAIL</root>"))
     856
     857          text = list(root[2].itertext())
     858          self.assertEqual(["CTEXT"],
     859                            text)
     860
     861 -    def test_findall(self):
     862          XML = self.etree.XML
     863          root = XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>'))
     864          self.assertEqual(len(list(root.findall("c"))), 1)
     865          self.assertEqual(len(list(root.findall(".//c"))), 2)
     866          self.assertEqual(len(list(root.findall(".//b"))), 3)
     867          self.assertEqual(len(list(root.findall(".//b"))[0]), 1)
     868          self.assertEqual(len(list(root.findall(".//b"))[1]), 0)
     869          self.assertEqual(len(list(root.findall(".//b"))[2]), 0)
     870
     871 -    def test_findall_ns(self):
     872          XML = self.etree.XML
     873          root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
     874          self.assertEqual(len(list(root.findall(".//{X}b"))), 2)
     875          self.assertEqual(len(list(root.findall(".//b"))), 3)
     876          self.assertEqual(len(list(root.findall("b"))), 2)
     877
     878 -    def test_element_with_attributes_keywords(self):
     879          Element = self.etree.Element
     880
     881          el = Element('tag', foo='Foo', bar='Bar')
     882          self.assertEqual('Foo', el.attrib['foo'])
     883          self.assertEqual('Bar', el.attrib['bar'])
     884
     885 -    def test_element_with_attributes(self):
     886          Element = self.etree.Element
     887
     888          el = Element('tag', {'foo': 'Foo', 'bar': 'Bar'})
     889          self.assertEqual('Foo', el.attrib['foo'])
     890          self.assertEqual('Bar', el.attrib['bar'])
     891
     892 -    def test_element_with_attributes_extra(self):
     893          Element = self.etree.Element
     894
     895          el = Element('tag', {'foo': 'Foo', 'bar': 'Bar'}, baz='Baz')
     896          self.assertEqual('Foo', el.attrib['foo'])
     897          self.assertEqual('Bar', el.attrib['bar'])
     898          self.assertEqual('Baz', el.attrib['baz'])
     899
     900 -    def test_element_with_attributes_extra_duplicate(self):
     901          Element = self.etree.Element
     902
     903          el = Element('tag', {'foo': 'Foo', 'bar': 'Bar'}, bar='Baz')
     904          self.assertEqual('Foo', el.attrib['foo'])
     905          self.assertEqual('Baz', el.attrib['bar'])
     906
     907 -    def test_element_with_attributes_ns(self):
     908          Element = self.etree.Element
     909
     910          el = Element('tag', {'{ns1}foo':'Foo', '{ns2}bar':'Bar'})
     911          self.assertEqual('Foo', el.attrib['{ns1}foo'])
     912          self.assertEqual('Bar', el.attrib['{ns2}bar'])
     913
     914 -    def test_subelement_with_attributes(self):
     915          Element =  self.etree.Element
     916          SubElement = self.etree.SubElement
     917
     918          el = Element('tag')
     919          SubElement(el, 'foo', {'foo':'Foo'}, baz="Baz")
     920          self.assertEqual("Baz", el[0].attrib['baz'])
     921          self.assertEqual('Foo', el[0].attrib['foo'])
     922
     923 -    def test_subelement_with_attributes_ns(self):
     924          Element = self.etree.Element
     925          SubElement = self.etree.SubElement
     926
     927          el = Element('tag')
     928          SubElement(el, 'foo', {'{ns1}foo':'Foo', '{ns2}bar':'Bar'})
     929          self.assertEqual('Foo', el[0].attrib['{ns1}foo'])
     930          self.assertEqual('Bar', el[0].attrib['{ns2}bar'])
     931
     932 -    def test_write(self):
     933          ElementTree = self.etree.ElementTree
     934          XML = self.etree.XML
     935
     936          for i in range(10):
     937              f = BytesIO()
     938              root = XML(_bytes('<doc%s>This is a test.</doc%s>' % (i, i)))
     939              tree = ElementTree(element=root)
     940              tree.write(f)
     941              data = f.getvalue()
     942              self.assertEqual(
     943                  _bytes('<doc%s>This is a test.</doc%s>' % (i, i)),
     944                  canonicalize(data))
     945
     946      required_versions_ET['test_write_method_html'] = (1,3)
     947 -    def test_write_method_html(self):
     948          ElementTree = self.etree.ElementTree
     949          Element = self.etree.Element
     950          SubElement = self.etree.SubElement
     951
     952          html = Element('html')
     953          body = SubElement(html, 'body')
     954          p = SubElement(body, 'p')
     955          p.text = "html"
     956          SubElement(p, 'br').tail = "test"
     957
     958          tree = ElementTree(element=html)
     959          f = BytesIO()
     960          tree.write(f, method="html")
     961          data = f.getvalue().replace(_bytes('\n'),_bytes(''))
     962
     963          self.assertEqual(_bytes('<html><body><p>html<br>test</p></body></html>'),
     964                            data)
     965
     966      required_versions_ET['test_write_method_text'] = (1,3)
     967 -    def test_write_method_text(self):
     968          ElementTree = self.etree.ElementTree
     969          Element = self.etree.Element
     970          SubElement = self.etree.SubElement
     971
     972          a = Element('a')
     973          a.text = "A"
     974          a.tail = "tail"
     975          b = SubElement(a, 'b')
     976          b.text = "B"
     977          b.tail = "TAIL"
     978          c = SubElement(a, 'c')
     979          c.text = "C"
     980
     981          tree = ElementTree(element=a)
     982          f = BytesIO()
     983          tree.write(f, method="text")
     984          data = f.getvalue()
     985
     986          self.assertEqual(_bytes('ABTAILCtail'),
     987                            data)
     988
     989 -    def test_write_fail(self):
     990          ElementTree = self.etree.ElementTree
     991          XML = self.etree.XML
     992
     993          tree = ElementTree( XML(_bytes('<doc>This is a test.</doc>')) )
     994          self.assertRaises(IOError, tree.write,
     995                            "definitely////\\-\\nonexisting\\-\\////FILE")
     996
     997      # this could trigger a crash, apparently because the document
     998      # reference was prematurely garbage collected
     999 -    def test_crash(self):
    1000          Element = self.etree.Element
    1001
    1002          element = Element('tag')
    1003          for i in range(10):
    1004              element.attrib['key'] = 'value'
    1005              value = element.attrib['key']
    1006              self.assertEqual(value, 'value')
    1007
    1008      # from doctest; for some reason this caused crashes too
    1009 -    def test_write_ElementTreeDoctest(self):
    1010          Element = self.etree.Element
    1011          ElementTree = self.etree.ElementTree
    1012
    1013          f = BytesIO()
    1014          for i in range(10):
    1015              element = Element('tag%s' % i)
    1016              self._check_element(element)
    1017              tree = ElementTree(element)
    1018              tree.write(f)
    1019              self._check_element_tree(tree)
    1020
    1021 -    def test_subelement_reference(self):
    1022          Element = self.etree.Element
    1023          SubElement = self.etree.SubElement
    1024
    1025          el = Element('foo')
    1026          el2 = SubElement(el, 'bar')
    1027          el3 = SubElement(el2, 'baz')
    1028
    1029          al = Element('foo2')
    1030          al2 = SubElement(al, 'bar2')
    1031          al3 = SubElement(al2, 'baz2')
    1032
    1033          # now move al2 into el
    1034          el.append(al2)
    1035
    1036          # now change al3 directly
    1037          al3.text = 'baz2-modified'
    1038
    1039          # it should have changed through this route too
    1040          self.assertEqual(
    1041              'baz2-modified',
    1042              el[1][0].text)
    1043
    1044 -    def test_set_text(self):
    1045          Element = self.etree.Element
    1046          SubElement = self.etree.SubElement
    1047
    1048          a = Element('a')
    1049          b = SubElement(a, 'b')
    1050          a.text = 'hoi'
    1051          self.assertEqual(
    1052              'hoi',
    1053              a.text)
    1054          self.assertEqual(
    1055              'b',
    1056              a[0].tag)
    1057
    1058 -    def test_set_text2(self):
    1059          Element = self.etree.Element
    1060          SubElement = self.etree.SubElement
    1061
    1062          a = Element('a')
    1063          a.text = 'hoi'
    1064          b = SubElement(a ,'b')
    1065          self.assertEqual(
    1066              'hoi',
    1067              a.text)
    1068          self.assertEqual(
    1069              'b',
    1070              a[0].tag)
    1071
    1072 -    def test_set_text_none(self):
    1073          Element = self.etree.Element
    1074
    1075          a = Element('a')
    1076
    1077          a.text = 'foo'
    1078          a.text = None
    1079
    1080          self.assertEqual(
    1081              None,
    1082              a.text)
    1083          self.assertXML(_bytes('<a></a>'), a)
    1084
    1085 -    def test_set_text_empty(self):
    1086          Element = self.etree.Element
    1087
    1088          a = Element('a')
    1089          self.assertEqual(None, a.text)
    1090
    1091          a.text = ''
    1092          self.assertEqual('', a.text)
    1093          self.assertXML(_bytes('<a></a>'), a)
    1094
    1095 -    def test_tail1(self):
    1096          Element = self.etree.Element
    1097          SubElement = self.etree.SubElement
    1098
    1099          a = Element('a')
    1100          a.tail = 'dag'
    1101          self.assertEqual('dag',
    1102                            a.tail)
    1103          b = SubElement(a, 'b')
    1104          b.tail = 'hoi'
    1105          self.assertEqual('hoi',
    1106                            b.tail)
    1107          self.assertEqual('dag',
    1108                            a.tail)
    1109
    1110 -    def test_tail_append(self):
    1111          Element = self.etree.Element
    1112
    1113          a = Element('a')
    1114          b = Element('b')
    1115          b.tail = 'b_tail'
    1116          a.append(b)
    1117          self.assertEqual('b_tail',
    1118                            b.tail)
    1119
    1120 -    def test_tail_set_twice(self):
    1121          Element = self.etree.Element
    1122          SubElement = self.etree.SubElement
    1123
    1124          a = Element('a')
    1125          b = SubElement(a, 'b')
    1126          b.tail = 'foo'
    1127          b.tail = 'bar'
    1128          self.assertEqual('bar',
    1129                            b.tail)
    1130          self.assertXML(_bytes('<a><b></b>bar</a>'), a)
    1131
    1132 -    def test_tail_set_none(self):
    1133          Element = self.etree.Element
    1134          a = Element('a')
    1135          a.tail = 'foo'
    1136          a.tail = None
    1137          self.assertEqual(
    1138              None,
    1139              a.tail)
    1140          self.assertXML(_bytes('<a></a>'), a)
    1141
    1142      required_versions_ET['test_extend'] = (1,3)
    1143 -    def test_extend(self):
    1144          root = self.etree.Element('foo')
    1145          for i in range(3):
    1146              element = self.etree.SubElement(root, 'a%s' % i)
    1147              element.text = "text%d" % i
    1148              element.tail = "tail%d" % i
    1149
    1150          elements = []
    1151          for i in range(3):
    1152              new_element = self.etree.Element("test%s" % i)
    1153              new_element.text = "TEXT%s" % i
    1154              new_element.tail = "TAIL%s" % i
    1155              elements.append(new_element)
    1156
    1157          root.extend(elements)
    1158
    1159          self.assertEqual(
    1160              ["a0", "a1", "a2", "test0", "test1", "test2"],
    1161              [ el.tag for el in root ])
    1162          self.assertEqual(
    1163              ["text0", "text1", "text2", "TEXT0", "TEXT1", "TEXT2"],
    1164              [ el.text for el in root ])
    1165          self.assertEqual(
    1166              ["tail0", "tail1", "tail2", "TAIL0", "TAIL1", "TAIL2"],
    1167              [ el.tail for el in root ])
    1168
    1169 -    def test_comment(self):
    1170          Element = self.etree.Element
    1171          SubElement = self.etree.SubElement
    1172          Comment = self.etree.Comment
    1173
    1174          a = Element('a')
    1175          a.append(Comment('foo'))
    1176          self.assertEqual(a[0].tag, Comment)
    1177          self.assertEqual(a[0].text, 'foo')
    1178
    1179      # ElementTree < 1.3 adds whitespace around comments
    1180      required_versions_ET['test_comment_text'] = (1,3)
    1181 -    def test_comment_text(self):
    1182          Element = self.etree.Element
    1183          SubElement = self.etree.SubElement
    1184          Comment = self.etree.Comment
    1185          tostring = self.etree.tostring
    1186
    1187          a = Element('a')
    1188          a.append(Comment('foo'))
    1189          self.assertEqual(a[0].text, 'foo')
    1190
    1191          self.assertEqual(
    1192              _bytes('<a><!--foo--></a>'),
    1193              tostring(a))
    1194
    1195          a[0].text = "TEST"
    1196          self.assertEqual(a[0].text, 'TEST')
    1197
    1198          self.assertEqual(
    1199              _bytes('<a><!--TEST--></a>'),
    1200              tostring(a))
    1201
    1202      # ElementTree < 1.3 adds whitespace around comments
    1203      required_versions_ET['test_comment_whitespace'] = (1,3)
    1204 -    def test_comment_whitespace(self):
    1205          Element = self.etree.Element
    1206          SubElement = self.etree.SubElement
    1207          Comment = self.etree.Comment
    1208          tostring = self.etree.tostring
    1209
    1210          a = Element('a')
    1211          a.append(Comment(' foo  '))
    1212          self.assertEqual(a[0].text, ' foo  ')
    1213          self.assertEqual(
    1214              _bytes('<a><!-- foo  --></a>'),
    1215              tostring(a))
    1216
    1217 -    def test_comment_nonsense(self):
    1218          Comment = self.etree.Comment
    1219          c = Comment('foo')
    1220          self.assertEqual({}, c.attrib)
    1221          self.assertEqual([], list(c.keys()))
    1222          self.assertEqual([], list(c.items()))
    1223          self.assertEqual(None, c.get('hoi'))
    1224          self.assertEqual(0, len(c))
    1225          # should not iterate
    1226          for i in c:
    1227              pass
    1228
    1229 -    def test_pi(self):
    1230          # lxml.etree separates target and text
    1231          Element = self.etree.Element
    1232          SubElement = self.etree.SubElement
    1233          ProcessingInstruction = self.etree.ProcessingInstruction
    1234
    1235          a = Element('a')
    1236          a.append(ProcessingInstruction('foo', 'some more text'))
    1237          self.assertEqual(a[0].tag, ProcessingInstruction)
    1238          self.assertXML(_bytes("<a><?foo some more text?></a>"),
    1239                         a)
    1240
    1241 -    def test_processinginstruction(self):
    1242          # lxml.etree separates target and text
    1243          Element = self.etree.Element
    1244          SubElement = self.etree.SubElement
    1245          ProcessingInstruction = self.etree.PI
    1246
    1247          a = Element('a')
    1248          a.append(ProcessingInstruction('foo', 'some more text'))
    1249          self.assertEqual(a[0].tag, ProcessingInstruction)
    1250          self.assertXML(_bytes("<a><?foo some more text?></a>"),
    1251                         a)
    1252
    1253 -    def test_pi_nonsense(self):
    1254          ProcessingInstruction = self.etree.ProcessingInstruction
    1255          pi = ProcessingInstruction('foo')
    1256          self.assertEqual({}, pi.attrib)
    1257          self.assertEqual([], list(pi.keys()))
    1258          self.assertEqual([], list(pi.items()))
    1259          self.assertEqual(None, pi.get('hoi'))
    1260          self.assertEqual(0, len(pi))
    1261          # should not iterate
    1262          for i in pi:
    1263              pass
    1264
    1265 -    def test_setitem(self):
    1266          Element = self.etree.Element
    1267          SubElement = self.etree.SubElement
    1268
    1269          a = Element('a')
    1270          b = SubElement(a, 'b')
    1271          c = Element('c')
    1272          a[0] = c
    1273          self.assertEqual(
    1274              c,
    1275              a[0])
    1276          self.assertXML(_bytes('<a><c></c></a>'),
    1277                         a)
    1278          self.assertXML(_bytes('<b></b>'),
    1279                         b)
    1280
    1281 -    def test_setitem2(self):
    1282          Element = self.etree.Element
    1283          SubElement = self.etree.SubElement
    1284
    1285          a = Element('a')
    1286          for i in range(5):
    1287              b = SubElement(a, 'b%s' % i)
    1288              c = SubElement(b, 'c')
    1289          for i in range(5):
    1290              d = Element('d')
    1291              e = SubElement(d, 'e')
    1292              a[i] = d
    1293          self.assertXML(
    1294              _bytes('<a><d><e></e></d><d><e></e></d><d><e></e></d><d><e></e></d><d><e></e></d></a>'),
    1295              a)
    1296          self.assertXML(_bytes('<c></c>'),
    1297                         c)
    1298
    1299 -    def test_setitem_replace(self):
    1300          Element = self.etree.Element
    1301          SubElement = self.etree.SubElement
    1302
    1303          a = Element('a')
    1304          SubElement(a, 'b')
    1305          d = Element('d')
    1306          a[0] = d
    1307          self.assertXML(_bytes('<a><d></d></a>'), a)
    1308
    1309 -    def test_setitem_indexerror(self):
    1310          Element = self.etree.Element
    1311          SubElement = self.etree.SubElement
    1312
    1313          a = Element('a')
    1314          b = SubElement(a, 'b')
    1315
    1316          self.assertRaises(IndexError, operator.setitem, a, 1, Element('c'))
    1317
    1318 -    def test_setitem_tail(self):
    1319          Element = self.etree.Element
    1320          SubElement = self.etree.SubElement
    1321
    1322          a = Element('a')
    1323          b = SubElement(a, 'b')
    1324          b.tail = 'B2'
    1325          c = Element('c')
    1326          c.tail = 'C2'
    1327
    1328          a[0] = c
    1329          self.assertXML(
    1330              _bytes('<a><c></c>C2</a>'),
    1331              a)
    1332
    1333 -    def test_tag_write(self):
    1334          Element = self.etree.Element
    1335          SubElement = self.etree.SubElement
    1336
    1337          a = Element('a')
    1338          b = SubElement(a, 'b')
    1339
    1340          a.tag = 'c'
    1341
    1342          self.assertEqual(
    1343              'c',
    1344              a.tag)
    1345
    1346          self.assertXML(
    1347              _bytes('<c><b></b></c>'),
    1348              a)
    1349
    1350 -    def test_tag_reset_ns(self):
    1351          Element = self.etree.Element
    1352          SubElement = self.etree.SubElement
    1353          tostring = self.etree.tostring
    1354
    1355          a = Element('{a}a')
    1356          b1 = SubElement(a, '{a}b')
    1357          b2 = SubElement(a, '{b}b')
    1358
    1359          self.assertEqual('{a}b',  b1.tag)
    1360
    1361          b1.tag = 'c'
    1362
    1363          # can't use C14N here!
    1364          self.assertEqual('c', b1.tag)
    1365          self.assertEqual(_bytes('<c'), tostring(b1)[:2])
    1366          self.assertTrue(_bytes('<c') in tostring(a))
    1367
    1368 -    def test_tag_reset_root_ns(self):
    1369          Element = self.etree.Element
    1370          SubElement = self.etree.SubElement
    1371          tostring = self.etree.tostring
    1372
    1373          a = Element('{a}a')
    1374          b1 = SubElement(a, '{a}b')
    1375          b2 = SubElement(a, '{b}b')
    1376
    1377          a.tag = 'c'
    1378
    1379          self.assertEqual(
    1380              'c',
    1381              a.tag)
    1382
    1383          # can't use C14N here!
    1384          self.assertEqual('c',  a.tag)
    1385          self.assertEqual(_bytes('<c'), tostring(a)[:2])
    1386
    1387 -    def test_tag_str_subclass(self):
    1388          Element = self.etree.Element
    1389
    1390          class strTest(str):
    1391              pass
    1392
    1393          a = Element("a")
    1394          a.tag = strTest("TAG")
    1395          self.assertXML(_bytes('<TAG></TAG>'),
    1396                         a)
    1397
    1398 -    def test_delitem(self):
    1399          Element = self.etree.Element
    1400          SubElement = self.etree.SubElement
    1401
    1402          a = Element('a')
    1403          b = SubElement(a, 'b')
    1404          c = SubElement(a, 'c')
    1405          d = SubElement(a, 'd')
    1406
    1407          del a[1]
    1408          self.assertXML(
    1409              _bytes('<a><b></b><d></d></a>'),
    1410              a)
    1411
    1412          del a[0]
    1413          self.assertXML(
    1414              _bytes('<a><d></d></a>'),
    1415              a)
    1416
    1417          del a[0]
    1418          self.assertXML(
    1419              _bytes('<a></a>'),
    1420              a)
    1421          # move deleted element into other tree afterwards
    1422          other = Element('other')
    1423          other.append(c)
    1424          self.assertXML(
    1425              _bytes('<other><c></c></other>'),
    1426              other)
    1427
    1428 -    def test_del_insert(self):
    1429          Element = self.etree.Element
    1430          SubElement = self.etree.SubElement
    1431
    1432          a = Element('a')
    1433          b = SubElement(a, 'b')
    1434          bs = SubElement(b, 'bs')
    1435          c = SubElement(a, 'c')
    1436          cs = SubElement(c, 'cs')
    1437
    1438          el = a[0]
    1439          self.assertXML(
    1440              _bytes('<a><b><bs></bs></b><c><cs></cs></c></a>'),
    1441              a)
    1442          self.assertXML(_bytes('<b><bs></bs></b>'), b)
    1443          self.assertXML(_bytes('<c><cs></cs></c>'), c)
    1444
    1445          del a[0]
    1446          self.assertXML(
    1447              _bytes('<a><c><cs></cs></c></a>'),
    1448              a)
    1449          self.assertXML(_bytes('<b><bs></bs></b>'), b)
    1450          self.assertXML(_bytes('<c><cs></cs></c>'), c)
    1451
    1452          a.insert(0, el)
    1453          self.assertXML(
    1454              _bytes('<a><b><bs></bs></b><c><cs></cs></c></a>'),
    1455              a)
    1456          self.assertXML(_bytes('<b><bs></bs></b>'), b)
    1457          self.assertXML(_bytes('<c><cs></cs></c>'), c)
    1458
    1459 -    def test_del_setitem(self):
    1460          Element = self.etree.Element
    1461          SubElement = self.etree.SubElement
    1462
    1463          a = Element('a')
    1464          b = SubElement(a, 'b')
    1465          bs = SubElement(b, 'bs')
    1466          c = SubElement(a, 'c')
    1467          cs = SubElement(c, 'cs')
    1468
    1469          el = a[0]
    1470          del a[0]
    1471          a[0] = el
    1472          self.assertXML(
    1473              _bytes('<a><b><bs></bs></b></a>'),
    1474              a)
    1475          self.assertXML(_bytes('<b><bs></bs></b>'), b)
    1476          self.assertXML(_bytes('<c><cs></cs></c>'), c)
    1477
    1478 -    def test_del_setslice(self):
    1479          Element = self.etree.Element
    1480          SubElement = self.etree.SubElement
    1481
    1482          a = Element('a')
    1483          b = SubElement(a, 'b')
    1484          bs = SubElement(b, 'bs')
    1485          c = SubElement(a, 'c')
    1486          cs = SubElement(c, 'cs')
    1487
    1488          el = a[0]
    1489          del a[0]
    1490          a[0:0] = [el]
    1491          self.assertXML(
    1492              _bytes('<a><b><bs></bs></b><c><cs></cs></c></a>'),
    1493              a)
    1494          self.assertXML(_bytes('<b><bs></bs></b>'), b)
    1495          self.assertXML(_bytes('<c><cs></cs></c>'), c)
    1496
    1497 -    def test_replace_slice_tail(self):
    1498          XML = self.etree.XML
    1499          a = XML(_bytes('<a><b></b>B2<c></c>C2</a>'))
    1500          b, c = a
    1501
    1502          a[:] = []
    1503
    1504          self.assertEqual("B2", b.tail)
    1505          self.assertEqual("C2", c.tail)
    1506
    1507 -    def test_merge_namespaced_subtree_as_slice(self):
    1508          XML = self.etree.XML
    1509          root = XML(_bytes(
    1510              '<foo><bar xmlns:baz="http://huhu"><puh><baz:bump1 /><baz:bump2 /></puh></bar></foo>'))
    1511          root[:] = root.findall('.//puh') # delete bar from hierarchy
    1512
    1513          # previously, this lost a namespace declaration on bump2
    1514          result = self.etree.tostring(root)
    1515          foo = self.etree.fromstring(result)
    1516
    1517          self.assertEqual('puh', foo[0].tag)
    1518          self.assertEqual('{http://huhu}bump1', foo[0][0].tag)
    1519          self.assertEqual('{http://huhu}bump2', foo[0][1].tag)
    1520
    1521 -    def test_delitem_tail(self):
    1522          ElementTree = self.etree.ElementTree
    1523          f = BytesIO('<a><b></b>B2<c></c>C2</a>')
    1524          doc = ElementTree(file=f)
    1525          a = doc.getroot()
    1526          del a[0]
    1527          self.assertXML(
    1528              _bytes('<a><c></c>C2</a>'),
    1529              a)
    1530
    1531 -    def test_clear(self):
    1532          Element = self.etree.Element
    1533
    1534          a = Element('a')
    1535          a.text = 'foo'
    1536          a.tail = 'bar'
    1537          a.set('hoi', 'dag')
    1538          a.clear()
    1539          self.assertEqual(None, a.text)
    1540          self.assertEqual(None, a.tail)
    1541          self.assertEqual(None, a.get('hoi'))
    1542          self.assertEqual('a', a.tag)
    1543
    1544 -    def test_clear_sub(self):
    1545          Element = self.etree.Element
    1546          SubElement = self.etree.SubElement
    1547
    1548          a = Element('a')
    1549          a.text = 'foo'
    1550          a.tail = 'bar'
    1551          a.set('hoi', 'dag')
    1552          b = SubElement(a, 'b')
    1553          c = SubElement(b, 'c')
    1554          a.clear()
    1555          self.assertEqual(None, a.text)
    1556          self.assertEqual(None, a.tail)
    1557          self.assertEqual(None, a.get('hoi'))
    1558          self.assertEqual('a', a.tag)
    1559          self.assertEqual(0, len(a))
    1560          self.assertXML(_bytes('<a></a>'),
    1561                         a)
    1562          self.assertXML(_bytes('<b><c></c></b>'),
    1563                         b)
    1564
    1565 -    def test_clear_tail(self):
    1566          ElementTree = self.etree.ElementTree
    1567          f = BytesIO('<a><b></b>B2<c></c>C2</a>')
    1568          doc = ElementTree(file=f)
    1569          a = doc.getroot()
    1570          a.clear()
    1571          self.assertXML(
    1572              _bytes('<a></a>'),
    1573              a)
    1574
    1575 -    def test_insert(self):
    1576          Element = self.etree.Element
    1577          SubElement = self.etree.SubElement
    1578
    1579          a = Element('a')
    1580          b = SubElement(a, 'b')
    1581          c = SubElement(a, 'c')
    1582          d = Element('d')
    1583          a.insert(0, d)
    1584
    1585          self.assertEqual(
    1586              d,
    1587              a[0])
    1588
    1589          self.assertXML(
    1590              _bytes('<a><d></d><b></b><c></c></a>'),
    1591              a)
    1592
    1593          e = Element('e')
    1594          a.insert(2, e)
    1595          self.assertEqual(
    1596              e,
    1597              a[2])
    1598          self.assertXML(
    1599              _bytes('<a><d></d><b></b><e></e><c></c></a>'),
    1600              a)
    1601
    1602 -    def test_insert_name_interning(self):
    1603          # See GH#268 / LP#1773749.
    1604          Element = self.etree.Element
    1605          SubElement = self.etree.SubElement
    1606
    1607          # Use unique names to make sure they are new in the tag name dict.
    1608          import uuid
    1609          names = dict((k, 'tag-' + str(uuid.uuid4())) for k in 'abcde')
    1610
    1611          a = Element(names['a'])
    1612          b = SubElement(a, names['b'])
    1613          c = SubElement(a, names['c'])
    1614          d = Element(names['d'])
    1615          a.insert(0, d)
    1616
    1617          self.assertEqual(
    1618              d,
    1619              a[0])
    1620
    1621          self.assertXML(
    1622              _bytes('<%(a)s><%(d)s></%(d)s><%(b)s></%(b)s><%(c)s></%(c)s></%(a)s>' % names),
    1623              a)
    1624
    1625          e = Element(names['e'])
    1626          a.insert(2, e)
    1627          self.assertEqual(
    1628              e,
    1629              a[2])
    1630          self.assertXML(
    1631              _bytes('<%(a)s><%(d)s></%(d)s><%(b)s></%(b)s><%(e)s></%(e)s><%(c)s></%(c)s></%(a)s>' % names),
    1632              a)
    1633
    1634 -    def test_insert_beyond_index(self):
    1635          Element = self.etree.Element
    1636          SubElement = self.etree.SubElement
    1637
    1638          a = Element('a')
    1639          b = SubElement(a, 'b')
    1640          c = Element('c')
    1641
    1642          a.insert(2, c)
    1643          self.assertEqual(
    1644              c,
    1645              a[1])
    1646          self.assertXML(
    1647              _bytes('<a><b></b><c></c></a>'),
    1648              a)
    1649
    1650 -    def test_insert_negative(self):
    1651          Element = self.etree.Element
    1652          SubElement = self.etree.SubElement
    1653
    1654          a = Element('a')
    1655          b = SubElement(a, 'b')
    1656          c = SubElement(a, 'c')
    1657
    1658          d = Element('d')
    1659          a.insert(-1, d)
    1660          self.assertEqual(
    1661              d,
    1662              a[-2])
    1663          self.assertXML(
    1664              _bytes('<a><b></b><d></d><c></c></a>'),
    1665              a)
    1666
    1667 -    def test_insert_tail(self):
    1668          Element = self.etree.Element
    1669          SubElement = self.etree.SubElement
    1670
    1671          a = Element('a')
    1672          b = SubElement(a, 'b')
    1673
    1674          c = Element('c')
    1675          c.tail = 'C2'
    1676
    1677          a.insert(0, c)
    1678          self.assertXML(
    1679              _bytes('<a><c></c>C2<b></b></a>'),
    1680              a)
    1681
    1682 -    def test_remove(self):
    1683          Element = self.etree.Element
    1684          SubElement = self.etree.SubElement
    1685
    1686          a = Element('a')
    1687          b = SubElement(a, 'b')
    1688          c = SubElement(a, 'c')
    1689
    1690          a.remove(b)
    1691          self.assertEqual(
    1692              c,
    1693              a[0])
    1694          self.assertXML(
    1695              _bytes('<a><c></c></a>'),
    1696              a)
    1697
    1698 -    def test_remove_ns(self):
    1699          Element = self.etree.Element
    1700          SubElement = self.etree.SubElement
    1701
    1702          a = Element('{http://test}a')
    1703          b = SubElement(a, '{http://test}b')
    1704          c = SubElement(a, '{http://test}c')
    1705
    1706          a.remove(b)
    1707          self.assertXML(
    1708              _bytes('<ns0:a xmlns:ns0="http://test"><ns0:c></ns0:c></ns0:a>'),
    1709              a)
    1710          self.assertXML(
    1711              _bytes('<ns0:b xmlns:ns0="http://test"></ns0:b>'),
    1712              b)
    1713
    1714 -    def test_remove_nonexisting(self):
    1715          Element = self.etree.Element
    1716          SubElement = self.etree.SubElement
    1717
    1718          a = Element('a')
    1719          b = SubElement(a, 'b')
    1720          c = SubElement(a, 'c')
    1721          d = Element('d')
    1722          self.assertRaises(
    1723              ValueError, a.remove, d)
    1724
    1725 -    def test_remove_tail(self):
    1726          Element = self.etree.Element
    1727          SubElement = self.etree.SubElement
    1728
    1729          a = Element('a')
    1730          b = SubElement(a, 'b')
    1731          b.tail = 'b2'
    1732          a.remove(b)
    1733          self.assertXML(
    1734              _bytes('<a></a>'),
    1735              a)
    1736          self.assertEqual('b2', b.tail)
    1737
    1738 -    def _test_getchildren(self):
    1739          Element = self.etree.Element
    1740          SubElement = self.etree.SubElement
    1741
    1742          a = Element('a')
    1743          b = SubElement(a, 'b')
    1744          c = SubElement(a, 'c')
    1745          d = SubElement(b, 'd')
    1746          e = SubElement(c, 'e')
    1747          self.assertXML(
    1748              _bytes('<a><b><d></d></b><c><e></e></c></a>'),
    1749              a)
    1750          self.assertEqual(
    1751              [b, c],
    1752              a.getchildren())
    1753          self.assertEqual(
    1754              [d],
    1755              b.getchildren())
    1756          self.assertEqual(
    1757              [],
    1758              d.getchildren())
    1759
    1760 -    def test_makeelement(self):
    1761          Element = self.etree.Element
    1762
    1763          a = Element('a')
    1764          b = a.makeelement('c', {'hoi':'dag'})
    1765          self.assertXML(
    1766              _bytes('<c hoi="dag"></c>'),
    1767              b)
    1768
    1769      required_versions_ET['test_iter'] = (1,3)
    1770 -    def test_iter(self):
    1771          Element = self.etree.Element
    1772          SubElement = self.etree.SubElement
    1773
    1774          a = Element('a')
    1775          b = SubElement(a, 'b')
    1776          c = SubElement(a, 'c')
    1777          d = SubElement(b, 'd')
    1778          e = SubElement(c, 'e')
    1779
    1780          self.assertEqual(
    1781              [a, b, d, c, e],
    1782              list(a.iter()))
    1783          self.assertEqual(
    1784              [d],
    1785              list(d.iter()))
    1786
    1787 -    def test_getiterator(self):
    1788          Element = self.etree.Element
    1789          SubElement = self.etree.SubElement
    1790
    1791          a = Element('a')
    1792          b = SubElement(a, 'b')
    1793          c = SubElement(a, 'c')
    1794          d = SubElement(b, 'd')
    1795          e = SubElement(c, 'e')
    1796
    1797          self.assertEqual(
    1798              [a, b, d, c, e],
    1799              list(a.getiterator()))
    1800          self.assertEqual(
    1801              [d],
    1802              list(d.getiterator()))
    1803
    1804 -    def test_getiterator_empty(self):
    1805          Element = self.etree.Element
    1806          SubElement = self.etree.SubElement
    1807
    1808          a = Element('a')
    1809          b = SubElement(a, 'b')
    1810          c = SubElement(a, 'c')
    1811          d = SubElement(b, 'd')
    1812          e = SubElement(c, 'e')
    1813
    1814          self.assertEqual(
    1815              [],
    1816              list(a.getiterator('none')))
    1817          self.assertEqual(
    1818              [],
    1819              list(e.getiterator('none')))
    1820          self.assertEqual(
    1821              [e],
    1822              list(e.getiterator()))
    1823
    1824 -    def test_getiterator_filter(self):
    1825          Element = self.etree.Element
    1826          SubElement = self.etree.SubElement
    1827
    1828          a = Element('a')
    1829          b = SubElement(a, 'b')
    1830          c = SubElement(a, 'c')
    1831          d = SubElement(b, 'd')
    1832          e = SubElement(c, 'e')
    1833
    1834          self.assertEqual(
    1835              [a],
    1836              list(a.getiterator('a')))
    1837          a2 = SubElement(e, 'a')
    1838          self.assertEqual(
    1839              [a, a2],
    1840              list(a.getiterator('a')))
    1841          self.assertEqual(
    1842              [a2],
    1843              list(c.getiterator('a')))
    1844
    1845 -    def test_getiterator_filter_all(self):
    1846          Element = self.etree.Element
    1847          SubElement = self.etree.SubElement
    1848
    1849          a = Element('a')
    1850          b = SubElement(a, 'b')
    1851          c = SubElement(a, 'c')
    1852          d = SubElement(b, 'd')
    1853          e = SubElement(c, 'e')
    1854
    1855          self.assertEqual(
    1856              [a, b, d, c, e],
    1857              list(a.getiterator('*')))
    1858
    1859 -    def test_getiterator_filter_comment(self):
    1860          Element = self.etree.Element
    1861          Comment = self.etree.Comment
    1862          SubElement = self.etree.SubElement
    1863
    1864          a = Element('a')
    1865          b = SubElement(a, 'b')
    1866          comment_b = Comment("TEST-b")
    1867          b.append(comment_b)
    1868
    1869          self.assertEqual(
    1870              [comment_b],
    1871              list(a.getiterator(Comment)))
    1872
    1873          comment_a = Comment("TEST-a")
    1874          a.append(comment_a)
    1875
    1876          self.assertEqual(
    1877              [comment_b, comment_a],
    1878              list(a.getiterator(Comment)))
    1879
    1880          self.assertEqual(
    1881              [comment_b],
    1882              list(b.getiterator(Comment)))
    1883
    1884 -    def test_getiterator_filter_pi(self):
    1885          Element = self.etree.Element
    1886          PI = self.etree.ProcessingInstruction
    1887          SubElement = self.etree.SubElement
    1888
    1889          a = Element('a')
    1890          b = SubElement(a, 'b')
    1891          pi_b = PI("TEST-b")
    1892          b.append(pi_b)
    1893
    1894          self.assertEqual(
    1895              [pi_b],
    1896              list(a.getiterator(PI)))
    1897
    1898          pi_a = PI("TEST-a")
    1899          a.append(pi_a)
    1900
    1901          self.assertEqual(
    1902              [pi_b, pi_a],
    1903              list(a.getiterator(PI)))
    1904
    1905          self.assertEqual(
    1906              [pi_b],
    1907              list(b.getiterator(PI)))
    1908
    1909 -    def test_getiterator_with_text(self):
    1910          Element = self.etree.Element
    1911          SubElement = self.etree.SubElement
    1912
    1913          a = Element('a')
    1914          a.text = 'a'
    1915          b = SubElement(a, 'b')
    1916          b.text = 'b'
    1917          b.tail = 'b1'
    1918          c = SubElement(a, 'c')
    1919          c.text = 'c'
    1920          c.tail = 'c1'
    1921          d = SubElement(b, 'd')
    1922          c.text = 'd'
    1923          c.tail = 'd1'
    1924          e = SubElement(c, 'e')
    1925          e.text = 'e'
    1926          e.tail = 'e1'
    1927
    1928          self.assertEqual(
    1929              [a, b, d, c, e],
    1930              list(a.getiterator()))
    1931          #self.assertEqual(
    1932          #    [d],
    1933          #    list(d.getiterator()))
    1934
    1935 -    def test_getiterator_filter_with_text(self):
    1936          Element = self.etree.Element
    1937          SubElement = self.etree.SubElement
    1938
    1939          a = Element('a')
    1940          a.text = 'a'
    1941          b = SubElement(a, 'b')
    1942          b.text = 'b'
    1943          b.tail = 'b1'
    1944          c = SubElement(a, 'c')
    1945          c.text = 'c'
    1946          c.tail = 'c1'
    1947          d = SubElement(b, 'd')
    1948          c.text = 'd'
    1949          c.tail = 'd1'
    1950          e = SubElement(c, 'e')
    1951          e.text = 'e'
    1952          e.tail = 'e1'
    1953
    1954          self.assertEqual(
    1955              [a],
    1956              list(a.getiterator('a')))
    1957          a2 = SubElement(e, 'a')
    1958          self.assertEqual(
    1959              [a, a2],
    1960              list(a.getiterator('a')))
    1961          self.assertEqual(
    1962              [a2],
    1963              list(e.getiterator('a')))
    1964
    1965 -    def test_getslice(self):
    1966          Element = self.etree.Element
    1967          SubElement = self.etree.SubElement
    1968
    1969          a = Element('a')
    1970          b = SubElement(a, 'b')
    1971          c = SubElement(a, 'c')
    1972          d = SubElement(a, 'd')
    1973
    1974          self.assertEqual(
    1975              [b, c],
    1976              a[0:2])
    1977          self.assertEqual(
    1978              [b, c, d],
    1979              a[:])
    1980          self.assertEqual(
    1981              [b, c, d],
    1982              a[:10])
    1983          self.assertEqual(
    1984              [b],
    1985              a[0:1])
    1986          self.assertEqual(
    1987              [],
    1988              a[10:12])
    1989
    1990 -    def test_getslice_negative(self):
    1991          Element = self.etree.Element
    1992          SubElement = self.etree.SubElement
    1993
    1994          a = Element('a')
    1995          b = SubElement(a, 'b')
    1996          c = SubElement(a, 'c')
    1997          d = SubElement(a, 'd')
    1998
    1999          self.assertEqual(
    2000              [d],
    2001              a[-1:])
    2002          self.assertEqual(
    2003              [c, d],
    2004              a[-2:])
    2005          self.assertEqual(
    2006              [c],
    2007              a[-2:-1])
    2008          self.assertEqual(
    2009              [b, c],
    2010              a[-3:-1])
    2011          self.assertEqual(
    2012              [b, c],
    2013              a[-3:2])
    2014
    2015 -    def test_getslice_step(self):
    2016          Element = self.etree.Element
    2017          SubElement = self.etree.SubElement
    2018
    2019          a = Element('a')
    2020          b = SubElement(a, 'b')
    2021          c = SubElement(a, 'c')
    2022          d = SubElement(a, 'd')
    2023          e = SubElement(a, 'e')
    2024
    2025          self.assertEqual(
    2026              [e,d,c,b],
    2027              a[::-1])
    2028          self.assertEqual(
    2029              [b,d],
    2030              a[::2])
    2031          self.assertEqual(
    2032              [e,c],
    2033              a[::-2])
    2034          self.assertEqual(
    2035              [d,c],
    2036              a[-2:0:-1])
    2037          self.assertEqual(
    2038              [e],
    2039              a[:1:-2])
    2040
    2041 -    def test_getslice_text(self):
    2042          ElementTree = self.etree.ElementTree
    2043
    2044          f = BytesIO('<a><b>B</b>B1<c>C</c>C1</a>')
    2045          doc = ElementTree(file=f)
    2046          a = doc.getroot()
    2047          b = a[0]
    2048          c = a[1]
    2049          self.assertEqual(
    2050              [b, c],
    2051              a[:])
    2052          self.assertEqual(
    2053              [b],
    2054              a[0:1])
    2055          self.assertEqual(
    2056              [c],
    2057              a[1:])
    2058
    2059 -    def test_comment_getitem_getslice(self):
    2060          Element = self.etree.Element
    2061          Comment = self.etree.Comment
    2062          SubElement = self.etree.SubElement
    2063
    2064          a = Element('a')
    2065          b = SubElement(a, 'b')
    2066          foo = Comment('foo')
    2067          a.append(foo)
    2068          c = SubElement(a, 'c')
    2069          self.assertEqual(
    2070              [b, foo, c],
    2071              a[:])
    2072          self.assertEqual(
    2073              foo,
    2074              a[1])
    2075          a[1] = new = Element('new')
    2076          self.assertEqual(
    2077              new,
    2078              a[1])
    2079          self.assertXML(
    2080              _bytes('<a><b></b><new></new><c></c></a>'),
    2081              a)
    2082
    2083 -    def test_delslice(self):
    2084          Element = self.etree.Element
    2085          SubElement = self.etree.SubElement
    2086
    2087          a = Element('a')
    2088          b = SubElement(a, 'b')
    2089          c = SubElement(a, 'c')
    2090          d = SubElement(a, 'd')
    2091          e = SubElement(a, 'e')
    2092
    2093          del a[1:3]
    2094          self.assertEqual(
    2095              [b, e],
    2096              list(a))
    2097
    2098 -    def test_delslice_negative1(self):
    2099          Element = self.etree.Element
    2100          SubElement = self.etree.SubElement
    2101
    2102          a = Element('a')
    2103          b = SubElement(a, 'b')
    2104          c = SubElement(a, 'c')
    2105          d = SubElement(a, 'd')
    2106          e = SubElement(a, 'e')
    2107
    2108          del a[1:-1]
    2109          self.assertEqual(
    2110              [b, e],
    2111              list(a))
    2112
    2113 -    def test_delslice_negative2(self):
    2114          Element = self.etree.Element
    2115          SubElement = self.etree.SubElement
    2116
    2117          a = Element('a')
    2118          b = SubElement(a, 'b')
    2119          c = SubElement(a, 'c')
    2120          d = SubElement(a, 'd')
    2121          e = SubElement(a, 'e')
    2122
    2123          del a[-3:-1]
    2124          self.assertEqual(
    2125              [b, e],
    2126              list(a))
    2127
    2128 -    def test_delslice_step(self):
    2129          Element = self.etree.Element
    2130          SubElement = self.etree.SubElement
    2131
    2132          a = Element('a')
    2133          b = SubElement(a, 'b')
    2134          c = SubElement(a, 'c')
    2135          d = SubElement(a, 'd')
    2136          e = SubElement(a, 'e')
    2137
    2138          del a[1::2]
    2139          self.assertEqual(
    2140              [b, d],
    2141              list(a))
    2142
    2143 -    def test_delslice_step_negative(self):
    2144          Element = self.etree.Element
    2145          SubElement = self.etree.SubElement
    2146
    2147          a = Element('a')
    2148          b = SubElement(a, 'b')
    2149          c = SubElement(a, 'c')
    2150          d = SubElement(a, 'd')
    2151          e = SubElement(a, 'e')
    2152
    2153          del a[::-1]
    2154          self.assertEqual(
    2155              [],
    2156              list(a))
    2157
    2158 -    def test_delslice_step_negative2(self):
    2159          Element = self.etree.Element
    2160          SubElement = self.etree.SubElement
    2161
    2162          a = Element('a')
    2163          b = SubElement(a, 'b')
    2164          c = SubElement(a, 'c')
    2165          d = SubElement(a, 'd')
    2166          e = SubElement(a, 'e')
    2167
    2168          del a[::-2]
    2169          self.assertEqual(
    2170              [b, d],
    2171              list(a))
    2172
    2173 -    def test_delslice_child_tail(self):
    2174          ElementTree = self.etree.ElementTree
    2175          f = BytesIO('<a><b></b>B2<c></c>C2<d></d>D2<e></e>E2</a>')
    2176          doc = ElementTree(file=f)
    2177          a = doc.getroot()
    2178          del a[1:3]
    2179          self.assertXML(
    2180              _bytes('<a><b></b>B2<e></e>E2</a>'),
    2181              a)
    2182
    2183 -    def test_delslice_tail(self):
    2184          XML = self.etree.XML
    2185          a = XML(_bytes('<a><b></b>B2<c></c>C2</a>'))
    2186          b, c = a
    2187
    2188          del a[:]
    2189
    2190          self.assertEqual("B2", b.tail)
    2191          self.assertEqual("C2", c.tail)
    2192
    2193 -    def test_delslice_memory(self):
    2194          # this could trigger a crash
    2195          Element = self.etree.Element
    2196          SubElement = self.etree.SubElement
    2197          a = Element('a')
    2198          b = SubElement(a, 'b')
    2199          c = SubElement(b, 'c')
    2200          del b # no more reference to b
    2201          del a[:]
    2202          self.assertEqual('c', c.tag)
    2203
    2204 -    def test_setslice(self):
    2205          Element = self.etree.Element
    2206          SubElement = self.etree.SubElement
    2207
    2208          a = Element('a')
    2209          b = SubElement(a, 'b')
    2210          c = SubElement(a, 'c')
    2211          d = SubElement(a, 'd')
    2212
    2213          e = Element('e')
    2214          f = Element('f')
    2215          g = Element('g')
    2216
    2217          s = [e, f, g]
    2218          a[1:2] = s
    2219          self.assertEqual(
    2220              [b, e, f, g, d],
    2221              list(a))
    2222
    2223 -    def test_setslice_all(self):
    2224          Element = self.etree.Element
    2225          SubElement = self.etree.SubElement
    2226
    2227          a = Element('a')
    2228          b = SubElement(a, 'b')
    2229          c = SubElement(a, 'c')
    2230
    2231          e = Element('e')
    2232          f = Element('f')
    2233          g = Element('g')
    2234
    2235          s = [e, f, g]
    2236          a[:] = s
    2237          self.assertEqual(
    2238              [e, f, g],
    2239              list(a))
    2240
    2241 -    def test_setslice_all_empty(self):
    2242          Element = self.etree.Element
    2243          SubElement = self.etree.SubElement
    2244
    2245          a = Element('a')
    2246
    2247          e = Element('e')
    2248          f = Element('f')
    2249          g = Element('g')
    2250
    2251          s = [e, f, g]
    2252          a[:] = s
    2253          self.assertEqual(
    2254              [e, f, g],
    2255              list(a))
    2256
    2257 -    def test_setslice_all_replace(self):
    2258          Element = self.etree.Element
    2259          SubElement = self.etree.SubElement
    2260
    2261          a = Element('a')
    2262          b = SubElement(a, 'b')
    2263          c = SubElement(a, 'c')
    2264          d = SubElement(a, 'd')
    2265
    2266          s = [b, c, d]
    2267          a[:] = s
    2268          self.assertEqual(
    2269              [b, c, d],
    2270              list(a))
    2271
    2272 -    def test_setslice_all_replace_reversed(self):
    2273          Element = self.etree.Element
    2274          SubElement = self.etree.SubElement
    2275
    2276          a = Element('a')
    2277          b = SubElement(a, 'b')
    2278          c = SubElement(a, 'c')
    2279          d = SubElement(a, 'd')
    2280
    2281          s = [d, c, b]
    2282          a[:] = s
    2283          self.assertEqual(
    2284              [d, c, b],
    2285              list(a))
    2286
    2287 -    def test_setslice_all_replace_reversed_ns1(self):
    2288          Element = self.etree.Element
    2289          SubElement = self.etree.SubElement
    2290
    2291          a = Element('{ns}a')
    2292          b = SubElement(a, '{ns}b', {'{ns1}a1': 'test'})
    2293          c = SubElement(a, '{ns}c', {'{ns2}a2': 'test'})
    2294          d = SubElement(a, '{ns}d', {'{ns3}a3': 'test'})
    2295
    2296          s = [d, c, b]
    2297          a[:] = s
    2298          self.assertEqual(
    2299              [d, c, b],
    2300              list(a))
    2301          self.assertEqual(
    2302              ['{ns}d', '{ns}c', '{ns}b'],
    2303              [ child.tag for child in a ])
    2304
    2305          self.assertEqual(
    2306              [['{ns3}a3'], ['{ns2}a2'], ['{ns1}a1']],
    2307              [ list(child.attrib.keys()) for child in a ])
    2308
    2309 -    def test_setslice_all_replace_reversed_ns2(self):
    2310          Element = self.etree.Element
    2311          SubElement = self.etree.SubElement
    2312
    2313          a = Element('{ns}a')
    2314          b = SubElement(a, '{ns1}b', {'{ns}a1': 'test'})
    2315          c = SubElement(a, '{ns2}c', {'{ns}a2': 'test'})
    2316          d = SubElement(a, '{ns3}d', {'{ns}a3': 'test'})
    2317
    2318          s = [d, c, b]
    2319          a[:] = s
    2320          self.assertEqual(
    2321              [d, c, b],
    2322              list(a))
    2323          self.assertEqual(
    2324              ['{ns3}d', '{ns2}c', '{ns1}b'],
    2325              [ child.tag for child in a ])
    2326
    2327          self.assertEqual(
    2328              [['{ns}a3'], ['{ns}a2'], ['{ns}a1']],
    2329              [ list(child.attrib.keys()) for child in a ])
    2330
    2331 -    def test_setslice_end(self):
    2332          Element = self.etree.Element
    2333          SubElement = self.etree.SubElement
    2334
    2335          a = Element('a')
    2336          b = SubElement(a, 'b')
    2337          c = SubElement(a, 'c')
    2338
    2339          e = Element('e')
    2340          f = Element('f')
    2341          g = Element('g')
    2342          h = Element('h')
    2343
    2344          s = [e, f]
    2345          a[99:] = s
    2346          self.assertEqual(
    2347              [b, c, e, f],
    2348              list(a))
    2349
    2350          s = [g, h]
    2351          a[:0] = s
    2352          self.assertEqual(
    2353              [g, h, b, c, e, f],
    2354              list(a))
    2355
    2356 -    def test_setslice_end_exact(self):
    2357          Element = self.etree.Element
    2358          SubElement = self.etree.SubElement
    2359
    2360          a = Element('a')
    2361          b = SubElement(a, 'b')
    2362          c = SubElement(a, 'c')
    2363          d = SubElement(a, 'd')
    2364
    2365          e = Element('e')
    2366          f = Element('f')
    2367          g = Element('g')
    2368
    2369          s = [e, f, g]
    2370          a[3:] = s
    2371          self.assertEqual(
    2372              [b, c, d, e, f, g],
    2373              list(a))
    2374
    2375 -    def test_setslice_single(self):
    2376          Element = self.etree.Element
    2377          SubElement = self.etree.SubElement
    2378
    2379          a = Element('a')
    2380          b = SubElement(a, 'b')
    2381          c = SubElement(a, 'c')
    2382
    2383          e = Element('e')
    2384          f = Element('f')
    2385
    2386          s = [e]
    2387          a[0:1] = s
    2388          self.assertEqual(
    2389              [e, c],
    2390              list(a))
    2391
    2392          s = [f]
    2393          a[1:2] = s
    2394          self.assertEqual(
    2395              [e, f],
    2396              list(a))
    2397
    2398 -    def test_setslice_tail(self):
    2399          ElementTree = self.etree.ElementTree
    2400          Element = self.etree.Element
    2401          f = BytesIO('<a><b></b>B2<c></c>C2<d></d>D2<e></e>E2</a>')
    2402          doc = ElementTree(file=f)
    2403          a = doc.getroot()
    2404          x = Element('x')
    2405          y = Element('y')
    2406          z = Element('z')
    2407          x.tail = 'X2'
    2408          y.tail = 'Y2'
    2409          z.tail = 'Z2'
    2410          a[1:3] = [x, y, z]
    2411          self.assertXML(
    2412              _bytes('<a><b></b>B2<x></x>X2<y></y>Y2<z></z>Z2<e></e>E2</a>'),
    2413              a)
    2414
    2415 -    def test_setslice_negative(self):
    2416          Element = self.etree.Element
    2417          SubElement = self.etree.SubElement
    2418
    2419          a = Element('a')
    2420          b = SubElement(a, 'b')
    2421          c = SubElement(a, 'c')
    2422          d = SubElement(a, 'd')
    2423
    2424          x = Element('x')
    2425          y = Element('y')
    2426
    2427          a[1:-1] = [x, y]
    2428          self.assertEqual(
    2429              [b, x, y, d],
    2430              list(a))
    2431
    2432 -    def test_setslice_negative2(self):
    2433          Element = self.etree.Element
    2434          SubElement = self.etree.SubElement
    2435
    2436          a = Element('a')
    2437          b = SubElement(a, 'b')
    2438          c = SubElement(a, 'c')
    2439          d = SubElement(a, 'd')
    2440
    2441          x = Element('x')
    2442          y = Element('y')
    2443
    2444          a[1:-2] = [x, y]
    2445          self.assertEqual(
    2446              [b, x, y, c, d],
    2447              list(a))
    2448
    2449 -    def test_setslice_empty(self):
    2450          Element = self.etree.Element
    2451
    2452          a = Element('a')
    2453
    2454          b = Element('b')
    2455          c = Element('c')
    2456
    2457          a[:] = [b, c]
    2458          self.assertEqual(
    2459              [b, c],
    2460              list(a))
    2461
    2462 -    def test_tail_elementtree_root(self):
    2463          Element = self.etree.Element
    2464          ElementTree = self.etree.ElementTree
    2465
    2466          a = Element('a')
    2467          a.tail = 'A2'
    2468          t = ElementTree(element=a)
    2469          self.assertEqual('A2',
    2470                            a.tail)
    2471
    2472 -    def test_elementtree_getiterator(self):
    2473          Element = self.etree.Element
    2474          SubElement = self.etree.SubElement
    2475          ElementTree = self.etree.ElementTree
    2476
    2477          a = Element('a')
    2478          b = SubElement(a, 'b')
    2479          c = SubElement(a, 'c')
    2480          d = SubElement(b, 'd')
    2481          e = SubElement(c, 'e')
    2482          t = ElementTree(element=a)
    2483
    2484          self.assertEqual(
    2485              [a, b, d, c, e],
    2486              list(t.getiterator()))
    2487
    2488 -    def test_elementtree_getiterator_filter(self):
    2489          Element = self.etree.Element
    2490          SubElement = self.etree.SubElement
    2491          ElementTree = self.etree.ElementTree
    2492          a = Element('a')
    2493          b = SubElement(a, 'b')
    2494          c = SubElement(a, 'c')
    2495          d = SubElement(b, 'd')
    2496          e = SubElement(c, 'e')
    2497          t = ElementTree(element=a)
    2498
    2499          self.assertEqual(
    2500              [a],
    2501              list(t.getiterator('a')))
    2502          a2 = SubElement(e, 'a')
    2503          self.assertEqual(
    2504              [a, a2],
    2505              list(t.getiterator('a')))
    2506
    2507 -    def test_ns_access(self):
    2508          ElementTree = self.etree.ElementTree
    2509          ns = 'http://xml.infrae.com/1'
    2510          f = BytesIO('<x:a xmlns:x="%s"><x:b></x:b></x:a>' % ns)
    2511          t = ElementTree(file=f)
    2512          a = t.getroot()
    2513          self.assertEqual('{%s}a' % ns,
    2514                            a.tag)
    2515          self.assertEqual('{%s}b' % ns,
    2516                            a[0].tag)
    2517
    2518 -    def test_ns_access2(self):
    2519          ElementTree = self.etree.ElementTree
    2520          ns = 'http://xml.infrae.com/1'
    2521          ns2 = 'http://xml.infrae.com/2'
    2522          f = BytesIO('<x:a xmlns:x="%s" xmlns:y="%s"><x:b></x:b><y:b></y:b></x:a>' % (ns, ns2))
    2523          t = ElementTree(file=f)
    2524          a = t.getroot()
    2525          self.assertEqual('{%s}a' % ns,
    2526                            a.tag)
    2527          self.assertEqual('{%s}b' % ns,
    2528                            a[0].tag)
    2529          self.assertEqual('{%s}b' % ns2,
    2530                            a[1].tag)
    2531
    2532 -    def test_ns_setting(self):
    2533          Element = self.etree.Element
    2534          SubElement = self.etree.SubElement
    2535          ns = 'http://xml.infrae.com/1'
    2536          ns2 = 'http://xml.infrae.com/2'
    2537          a = Element('{%s}a' % ns)
    2538          b = SubElement(a, '{%s}b' % ns2)
    2539          c = SubElement(a, '{%s}c' % ns)
    2540          self.assertEqual('{%s}a' % ns,
    2541                            a.tag)
    2542          self.assertEqual('{%s}b' % ns2,
    2543                            b.tag)
    2544          self.assertEqual('{%s}c' % ns,
    2545                            c.tag)
    2546          self.assertEqual('{%s}a' % ns,
    2547                            a.tag)
    2548          self.assertEqual('{%s}b' % ns2,
    2549                            b.tag)
    2550          self.assertEqual('{%s}c' % ns,
    2551                            c.tag)
    2552
    2553 -    def test_ns_tag_parse(self):
    2554          Element = self.etree.Element
    2555          SubElement = self.etree.SubElement
    2556          ElementTree = self.etree.ElementTree
    2557
    2558          ns = 'http://xml.infrae.com/1'
    2559          ns2 = 'http://xml.infrae.com/2'
    2560          f = BytesIO('<a xmlns="%s" xmlns:x="%s"><x:b></x:b><b></b></a>' % (ns, ns2))
    2561          t = ElementTree(file=f)
    2562
    2563          a = t.getroot()
    2564          self.assertEqual('{%s}a' % ns,
    2565                            a.tag)
    2566          self.assertEqual('{%s}b' % ns2,
    2567                            a[0].tag)
    2568          self.assertEqual('{%s}b' % ns,
    2569                            a[1].tag)
    2570
    2571 -    def test_ns_attr(self):
    2572          Element = self.etree.Element
    2573          ns = 'http://xml.infrae.com/1'
    2574          ns2 = 'http://xml.infrae.com/2'
    2575          a = Element('a')
    2576          a.set('{%s}foo' % ns, 'Foo')
    2577          a.set('{%s}bar' % ns2, 'Bar')
    2578          self.assertEqual(
    2579              'Foo',
    2580              a.get('{%s}foo' % ns))
    2581          self.assertEqual(
    2582              'Bar',
    2583              a.get('{%s}bar' % ns2))
    2584          try:
    2585              self.assertXML(
    2586                  _bytes('<a xmlns:ns0="%s" xmlns:ns1="%s" ns0:foo="Foo" ns1:bar="Bar"></a>' % (ns, ns2)),
    2587                  a)
    2588          except AssertionError:
    2589              self.assertXML(
    2590                  _bytes('<a xmlns:ns0="%s" xmlns:ns1="%s" ns1:foo="Foo" ns0:bar="Bar"></a>' % (ns2, ns)),
    2591                  a)
    2592
    2593 -    def test_ns_move(self):
    2594          Element = self.etree.Element
    2595          one = self.etree.fromstring(
    2596              _bytes('<foo><bar xmlns:ns="http://a.b.c"><ns:baz/></bar></foo>'))
    2597          baz = one[0][0]
    2598
    2599          two = Element('root')
    2600          two.append(baz)
    2601          # removing the originating document could cause a crash/error before
    2602          # as namespace is not moved along with it
    2603          del one, baz
    2604          self.assertEqual('{http://a.b.c}baz', two[0].tag)
    2605
    2606 -    def test_ns_decl_tostring(self):
    2607          tostring = self.etree.tostring
    2608          root = self.etree.XML(
    2609              _bytes('<foo><bar xmlns:ns="http://a.b.c"><ns:baz/></bar></foo>'))
    2610          baz = root[0][0]
    2611
    2612          nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
    2613                              tostring(baz))
    2614          self.assertEqual([_bytes("http://a.b.c")], nsdecl)
    2615
    2616 -    def test_ns_decl_tostring_default(self):
    2617          tostring = self.etree.tostring
    2618          root = self.etree.XML(
    2619              _bytes('<foo><bar xmlns="http://a.b.c"><baz/></bar></foo>'))
    2620          baz = root[0][0]
    2621
    2622          nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
    2623                              tostring(baz))
    2624          self.assertEqual([_bytes("http://a.b.c")], nsdecl)
    2625
    2626 -    def test_ns_decl_tostring_root(self):
    2627          tostring = self.etree.tostring
    2628          root = self.etree.XML(
    2629              _bytes('<foo xmlns:ns="http://a.b.c"><bar><ns:baz/></bar></foo>'))
    2630          baz = root[0][0]
    2631
    2632          nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
    2633                              tostring(baz))
    2634
    2635          self.assertEqual([_bytes("http://a.b.c")], nsdecl)
    2636
    2637 -    def test_ns_decl_tostring_element(self):
    2638          Element = self.etree.Element
    2639          SubElement = self.etree.SubElement
    2640
    2641          root = Element("foo")
    2642          bar = SubElement(root, "{http://a.b.c}bar")
    2643          baz = SubElement(bar, "{http://a.b.c}baz")
    2644
    2645          nsdecl = re.findall(_bytes("xmlns(?::[a-z0-9]+)?=[\"']([^\"']+)[\"']"),
    2646                              self.etree.tostring(baz))
    2647
    2648          self.assertEqual([_bytes("http://a.b.c")], nsdecl)
    2649
    2650 -    def test_attribute_xmlns_move(self):
    2651          Element = self.etree.Element
    2652
    2653          root = Element('element')
    2654
    2655          subelement = Element('subelement',
    2656                               {"{http://www.w3.org/XML/1998/namespace}id": "foo"})
    2657          self.assertEqual(1, len(subelement.attrib))
    2658          self.assertEqual(
    2659              "foo",
    2660              subelement.get("{http://www.w3.org/XML/1998/namespace}id"))
    2661
    2662          root.append(subelement)
    2663          self.assertEqual(1, len(subelement.attrib))
    2664          self.assertEqual(
    2665              list({"{http://www.w3.org/XML/1998/namespace}id" : "foo"}.items()),
    2666              list(subelement.attrib.items()))
    2667          self.assertEqual(
    2668              "foo",
    2669              subelement.get("{http://www.w3.org/XML/1998/namespace}id"))
    2670
    2671 -    def test_namespaces_after_serialize(self):
    2672          parse = self.etree.parse
    2673          tostring = self.etree.tostring
    2674
    2675          ns_href = "http://a.b.c"
    2676          one = parse(
    2677              BytesIO('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
    2678          baz = one.getroot()[0][0]
    2679
    2680          parsed = parse(BytesIO( tostring(baz) )).getroot()
    2681          self.assertEqual('{%s}baz' % ns_href, parsed.tag)
    2682
    2683 -    def test_attribute_namespace_roundtrip(self):
    2684          fromstring = self.etree.fromstring
    2685          tostring = self.etree.tostring
    2686
    2687          ns_href = "http://a.b.c"
    2688          xml = _bytes('<root xmlns="%s" xmlns:x="%s"><el x:a="test" /></root>' % (
    2689                  ns_href,ns_href))
    2690          root = fromstring(xml)
    2691          self.assertEqual('test', root[0].get('{%s}a' % ns_href))
    2692
    2693          xml2 = tostring(root)
    2694          self.assertTrue(_bytes(':a=') in xml2, xml2)
    2695
    2696          root2 = fromstring(xml2)
    2697          self.assertEqual('test', root2[0].get('{%s}a' % ns_href))
    2698
    2699 -    def test_attribute_namespace_roundtrip_replaced(self):
    2700          fromstring = self.etree.fromstring
    2701          tostring = self.etree.tostring
    2702
    2703          ns_href = "http://a.b.c"
    2704          xml = _bytes('<root xmlns="%s" xmlns:x="%s"><el x:a="test" /></root>' % (
    2705                  ns_href,ns_href))
    2706          root = fromstring(xml)
    2707          self.assertEqual('test', root[0].get('{%s}a' % ns_href))
    2708
    2709          root[0].set('{%s}a' % ns_href, 'TEST')
    2710
    2711          xml2 = tostring(root)
    2712          self.assertTrue(_bytes(':a=') in xml2, xml2)
    2713
    2714          root2 = fromstring(xml2)
    2715          self.assertEqual('TEST', root2[0].get('{%s}a' % ns_href))
    2716
    2717      required_versions_ET['test_register_namespace'] = (1,3)
    2718 -    def test_register_namespace(self):
    2719          # ET 1.3+
    2720          Element = self.etree.Element
    2721          prefix = 'TESTPREFIX'
    2722          namespace = 'http://seriously.unknown/namespace/URI'
    2723
    2724          el = Element('{%s}test' % namespace)
    2725          self.assertEqual(_bytes('<ns0:test xmlns:ns0="%s"></ns0:test>' % namespace),
    2726              self._writeElement(el))
    2727
    2728          self.etree.register_namespace(prefix, namespace)
    2729          el = Element('{%s}test' % namespace)
    2730          self.assertEqual(_bytes('<%s:test xmlns:%s="%s"></%s:test>' % (
    2731              prefix, prefix, namespace, prefix)),
    2732              self._writeElement(el))
    2733
    2734          self.assertRaises(ValueError, self.etree.register_namespace, 'ns25', namespace)
    2735
    2736 -    def test_tostring(self):
    2737          tostring = self.etree.tostring
    2738          Element = self.etree.Element
    2739          SubElement = self.etree.SubElement
    2740
    2741          a = Element('a')
    2742          b = SubElement(a, 'b')
    2743          c = SubElement(a, 'c')
    2744
    2745          self.assertEqual(_bytes('<a><b></b><c></c></a>'),
    2746                            canonicalize(tostring(a)))
    2747
    2748 -    def test_tostring_element(self):
    2749          tostring = self.etree.tostring
    2750          Element = self.etree.Element
    2751          SubElement = self.etree.SubElement
    2752
    2753          a = Element('a')
    2754          b = SubElement(a, 'b')
    2755          c = SubElement(a, 'c')
    2756          d = SubElement(c, 'd')
    2757          self.assertEqual(_bytes('<b></b>'),
    2758                            canonicalize(tostring(b)))
    2759          self.assertEqual(_bytes('<c><d></d></c>'),
    2760                            canonicalize(tostring(c)))
    2761
    2762 -    def test_tostring_element_tail(self):
    2763          tostring = self.etree.tostring
    2764          Element = self.etree.Element
    2765          SubElement = self.etree.SubElement
    2766
    2767          a = Element('a')
    2768          b = SubElement(a, 'b')
    2769          c = SubElement(a, 'c')
    2770          d = SubElement(c, 'd')
    2771          b.tail = 'Foo'
    2772
    2773          self.assertTrue(tostring(b) == _bytes('<b/>Foo') or
    2774                       tostring(b) == _bytes('<b />Foo'))
    2775
    2776      required_versions_ET['test_tostring_method_html'] = (1,3)
    2777 -    def test_tostring_method_html(self):
    2778          tostring = self.etree.tostring
    2779          Element = self.etree.Element
    2780          SubElement = self.etree.SubElement
    2781
    2782          html = Element('html')
    2783          body = SubElement(html, 'body')
    2784          p = SubElement(body, 'p')
    2785          p.text = "html"
    2786          SubElement(p, 'br').tail = "test"
    2787
    2788          self.assertEqual(_bytes('<html><body><p>html<br>test</p></body></html>'),
    2789                            tostring(html, method="html"))
    2790
    2791      required_versions_ET['test_tostring_method_text'] = (1,3)
    2792 -    def test_tostring_method_text(self):
    2793          tostring = self.etree.tostring
    2794          Element = self.etree.Element
    2795          SubElement = self.etree.SubElement
    2796
    2797          a = Element('a')
    2798          a.text = "A"
    2799          a.tail = "tail"
    2800          b = SubElement(a, 'b')
    2801          b.text = "B"
    2802          b.tail = "TAIL"
    2803          c = SubElement(a, 'c')
    2804          c.text = "C"
    2805
    2806          self.assertEqual(_bytes('ABTAILCtail'),
    2807                            tostring(a, method="text"))
    2808
    2809 -    def test_iterparse(self):
    2810          iterparse = self.etree.iterparse
    2811          f = BytesIO('<a><b></b><c/></a>')
    2812
    2813          iterator = iterparse(f)
    2814          self.assertEqual(None,
    2815                            iterator.root)
    2816          events = list(iterator)
    2817          root = iterator.root
    2818          self.assertEqual(
    2819              [('end', root[0]), ('end', root[1]), ('end', root)],
    2820              events)
    2821
    2822 -    def test_iterparse_incomplete(self):
    2823          iterparse = self.etree.iterparse
    2824          f = BytesIO('<a><b></b><c/></a>')
    2825
    2826          iterator = iterparse(f)
    2827          self.assertEqual(None,
    2828                            iterator.root)
    2829          event, element = next(iter(iterator))
    2830          self.assertEqual('end', event)
    2831          self.assertEqual('b', element.tag)
    2832
    2833 -    def test_iterparse_file(self):
    2834          iterparse = self.etree.iterparse
    2835          iterator = iterparse(fileInTestDir("test.xml"))
    2836          self.assertEqual(None,
    2837                            iterator.root)
    2838          events = list(iterator)
    2839          root = iterator.root
    2840          self.assertEqual(
    2841              [('end', root[0]), ('end', root)],
    2842              events)
    2843
    2844 -    def test_iterparse_start(self):
    2845          iterparse = self.etree.iterparse
    2846          f = BytesIO('<a><b></b><c/></a>')
    2847
    2848          iterator = iterparse(f, events=('start',))
    2849          events = list(iterator)
    2850          root = iterator.root
    2851          self.assertEqual(
    2852              [('start', root), ('start', root[0]), ('start', root[1])],
    2853              events)
    2854
    2855 -    def test_iterparse_start_end(self):
    2856          iterparse = self.etree.iterparse
    2857          f = BytesIO('<a><b></b><c/></a>')
    2858
    2859          iterator = iterparse(f, events=('start','end'))
    2860          events = list(iterator)
    2861          root = iterator.root
    2862          self.assertEqual(
    2863              [('start', root), ('start', root[0]), ('end', root[0]),
    2864               ('start', root[1]), ('end', root[1]), ('end', root)],
    2865              events)
    2866
    2867 -    def test_iterparse_clear(self):
    2868          iterparse = self.etree.iterparse
    2869          f = BytesIO('<a><b></b><c/></a>')
    2870
    2871          iterator = iterparse(f)
    2872          for event, elem in iterator:
    2873              elem.clear()
    2874
    2875          root = iterator.root
    2876          self.assertEqual(0,
    2877                            len(root))
    2878
    2879 -    def test_iterparse_large(self):
    2880          iterparse = self.etree.iterparse
    2881          CHILD_COUNT = 12345
    2882          f = BytesIO('<a>%s</a>' % ('<b>test</b>'*CHILD_COUNT))
    2883
    2884          i = 0
    2885          for key in iterparse(f):
    2886              event, element = key
    2887              i += 1
    2888          self.assertEqual(i, CHILD_COUNT + 1)
    2889
    2890 -    def test_iterparse_attrib_ns(self):
    2891          iterparse = self.etree.iterparse
    2892          f = BytesIO('<a xmlns="http://ns1/"><b><c xmlns="http://ns2/"/></b></a>')
    2893
    2894          attr_name = '{http://testns/}bla'
    2895          events = []
    2896          iterator = iterparse(f, events=('start','end','start-ns','end-ns'))
    2897          for event, elem in iterator:
    2898              events.append(event)
    2899              if event == 'start':
    2900                  if elem.tag != '{http://ns1/}a':
    2901                      elem.set(attr_name, 'value')
    2902
    2903          self.assertEqual(
    2904              ['start-ns', 'start', 'start', 'start-ns', 'start',
    2905               'end', 'end-ns', 'end', 'end', 'end-ns'],
    2906              events)
    2907
    2908          root = iterator.root
    2909          self.assertEqual(
    2910              None,
    2911              root.get(attr_name))
    2912          self.assertEqual(
    2913              'value',
    2914              root[0].get(attr_name))
    2915
    2916 -    def test_iterparse_getiterator(self):
    2917          iterparse = self.etree.iterparse
    2918          f = BytesIO('<a><b><d/></b><c/></a>')
    2919
    2920          counts = []
    2921          for event, elem in iterparse(f):
    2922              counts.append(len(list(elem.getiterator())))
    2923          self.assertEqual(
    2924              [1,2,1,4],
    2925              counts)
    2926
    2927 -    def test_iterparse_move_elements(self):
    2928          iterparse = self.etree.iterparse
    2929          f = BytesIO('<a><b><d/></b><c/></a>')
    2930
    2931          for event, node in etree.iterparse(f): pass
    2932
    2933          root = etree.Element('new_root', {})
    2934          root[:] = node[:]
    2935
    2936          self.assertEqual(
    2937              ['b', 'c'],
    2938              [ el.tag for el in root ])
    2939
    2940 -    def test_iterparse_cdata(self):
    2941          tostring = self.etree.tostring
    2942          f = BytesIO('<root><![CDATA[test]]></root>')
    2943          context = self.etree.iterparse(f)
    2944          content = [ el.text for event,el in context ]
    2945
    2946          self.assertEqual(['test'], content)
    2947          self.assertEqual(_bytes('<root>test</root>'),
    2948                            tostring(context.root))
    2949
    2950 -    def test_parse_file(self):
    2951          parse = self.etree.parse
    2952          # from file
    2953          tree = parse(fileInTestDir('test.xml'))
    2954          self.assertXML(
    2955              _bytes('<a><b></b></a>'),
    2956              tree.getroot())
    2957
    2958 -    def test_parse_file_nonexistent(self):
    2959          parse = self.etree.parse
    2960          self.assertRaises(IOError, parse, fileInTestDir('notthere.xml'))
    2961
    2962 -    def test_parse_error_none(self):
    2963          parse = self.etree.parse
    2964          self.assertRaises(TypeError, parse, None)
    2965
    2966      required_versions_ET['test_parse_error'] = (1,3)
    2967 -    def test_parse_error(self):
    2968          # ET < 1.3 raises ExpatError
    2969          parse = self.etree.parse
    2970          f = BytesIO('<a><b></c></b></a>')
    2971          self.assertRaises(SyntaxError, parse, f)
    2972          f.close()
    2973
    2974      required_versions_ET['test_parse_error_from_file'] = (1,3)
    2975 -    def test_parse_error_from_file(self):
    2976          parse = self.etree.parse
    2977          # from file
    2978          f = open(fileInTestDir('test_broken.xml'), 'rb')
    2979          self.assertRaises(SyntaxError, parse, f)
    2980          f.close()
    2981
    2982 -    def test_parse_file_object(self):
    2983          parse = self.etree.parse
    2984          # from file object
    2985          f = open(fileInTestDir('test.xml'), 'rb')
    2986          tree = parse(f)
    2987          f.close()
    2988          self.assertXML(
    2989              _bytes('<a><b></b></a>'),
    2990              tree.getroot())
    2991
    2992 -    def test_parse_stringio(self):
    2993          parse = self.etree.parse
    2994          f = BytesIO('<a><b></b></a>')
    2995          tree = parse(f)
    2996          f.close()
    2997          self.assertXML(
    2998              _bytes('<a><b></b></a>'),
    2999              tree.getroot()
    3000             )
    3001
    3002 -    def test_parse_cdata(self):
    3003          tostring = self.etree.tostring
    3004          root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'))
    3005
    3006          self.assertEqual('test', root.text)
    3007          self.assertEqual(_bytes('<root>test</root>'),
    3008                            tostring(root))
    3009
    3010 -    def test_parse_with_encoding(self):
    3011          # this can fail in libxml2 <= 2.6.22
    3012          parse = self.etree.parse
    3013          tree = parse(BytesIO('<?xml version="1.0" encoding="ascii"?><html/>'))
    3014          self.assertXML(_bytes('<html></html>'),
    3015                         tree.getroot())
    3016
    3017 -    def test_encoding(self):
    3018          Element = self.etree.Element
    3019
    3020          a = Element('a')
    3021          a.text = _str('Søk på nettet')
    3022          self.assertXML(
    3023              _str('<a>Søk på nettet</a>').encode('UTF-8'),
    3024              a, 'utf-8')
    3025
    3026 -    def test_encoding_exact(self):
    3027          ElementTree = self.etree.ElementTree
    3028          Element = self.etree.Element
    3029
    3030          a = Element('a')
    3031          a.text = _str('Søk på nettet')
    3032
    3033          f = BytesIO()
    3034          tree = ElementTree(element=a)
    3035          tree.write(f, encoding='utf-8')
    3036          self.assertEqual(_str('<a>Søk på nettet</a>').encode('UTF-8'),
    3037                            f.getvalue().replace(_bytes('\n'),_bytes('')))
    3038
    3039 -    def test_parse_file_encoding(self):
    3040          parse = self.etree.parse
    3041          # from file
    3042          tree = parse(fileInTestDir('test-string.xml'))
    3043          self.assertXML(
    3044              _str('<a>Søk på nettet</a>').encode('UTF-8'),
    3045              tree.getroot(), 'UTF-8')
    3046
    3047 -    def test_parse_file_object_encoding(self):
    3048          parse = self.etree.parse
    3049          # from file object
    3050          f = open(fileInTestDir('test-string.xml'), 'rb')
    3051          tree = parse(f)
    3052          f.close()
    3053          self.assertXML(
    3054              _str('<a>Søk på nettet</a>').encode('UTF-8'),
    3055              tree.getroot(), 'UTF-8')
    3056
    3057 -    def test_encoding_8bit_latin1(self):
    3058          ElementTree = self.etree.ElementTree
    3059          Element = self.etree.Element
    3060
    3061          a = Element('a')
    3062          a.text = _str('Søk på nettet')
    3063
    3064          f = BytesIO()
    3065          tree = ElementTree(element=a)
    3066          tree.write(f, encoding='iso-8859-1')
    3067          result = f.getvalue()
    3068          declaration = _bytes("<?xml version=\'1.0\' encoding=\'iso-8859-1\'?>")
    3069          self.assertEncodingDeclaration(result, _bytes('iso-8859-1'))
    3070          result = result.split(_bytes('?>'), 1)[-1].replace(_bytes('\n'),_bytes(''))
    3071          self.assertEqual(_str('<a>Søk på nettet</a>').encode('iso-8859-1'),
    3072                            result)
    3073
    3074      required_versions_ET['test_parse_encoding_8bit_explicit'] = (1,3)
    3075 -    def test_parse_encoding_8bit_explicit(self):
    3076          XMLParser = self.XMLParser
    3077
    3078          text = _str('Søk på nettet')
    3079          xml_latin1 = (_str('<a>%s</a>') % text).encode('iso-8859-1')
    3080
    3081          self.assertRaises(self.etree.ParseError,
    3082                            self.etree.parse,
    3083                            BytesIO(xml_latin1))
    3084
    3085          tree = self.etree.parse(BytesIO(xml_latin1),
    3086                                  XMLParser(encoding="iso-8859-1"))
    3087          a = tree.getroot()
    3088          self.assertEqual(a.text, text)
    3089
    3090      required_versions_ET['test_parse_encoding_8bit_override'] = (1,3)
    3091 -    def test_parse_encoding_8bit_override(self):
    3092          XMLParser = self.XMLParser
    3093
    3094          text = _str('Søk på nettet')
    3095          wrong_declaration = _str("<?xml version='1.0' encoding='UTF-8'?>")
    3096          xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
    3097                        ).encode('iso-8859-1')
    3098
    3099          self.assertRaises(self.etree.ParseError,
    3100                            self.etree.parse,
    3101                            BytesIO(xml_latin1))
    3102
    3103          tree = self.etree.parse(BytesIO(xml_latin1),
    3104                                  XMLParser(encoding="iso-8859-1"))
    3105          a = tree.getroot()
    3106          self.assertEqual(a.text, text)
    3107
    3108 -    def _test_wrong_unicode_encoding(self):
    3109          # raise error on wrong encoding declaration in unicode strings
    3110          XML = self.etree.XML
    3111          test_utf = (_str('<?xml version="1.0" encoding="iso-8859-1"?>') +
    3112                      _str('<a>Søk på nettet</a>'))
    3113          self.assertRaises(SyntaxError, XML, test_utf)
    3114
    3115 -    def test_encoding_write_default_encoding(self):
    3116          ElementTree = self.etree.ElementTree
    3117          Element = self.etree.Element
    3118
    3119          a = Element('a')
    3120          a.text = _str('Søk på nettet')
    3121
    3122          f = BytesIO()
    3123          tree = ElementTree(element=a)
    3124          tree.write(f)
    3125          data = f.getvalue().replace(_bytes('\n'),_bytes(''))
    3126          self.assertEqual(
    3127              _str('<a>Søk på nettet</a>').encode('ASCII', 'xmlcharrefreplace'),
    3128              data)
    3129
    3130 -    def test_encoding_tostring(self):
    3131          Element = self.etree.Element
    3132          tostring = self.etree.tostring
    3133
    3134          a = Element('a')
    3135          a.text = _str('Søk på nettet')
    3136          self.assertEqual(_str('<a>Søk på nettet</a>').encode('UTF-8'),
    3137                           tostring(a, encoding='utf-8'))
    3138
    3139 -    def test_encoding_tostring_unknown(self):
    3140          Element = self.etree.Element
    3141          tostring = self.etree.tostring
    3142
    3143          a = Element('a')
    3144          a.text = _str('Søk på nettet')
    3145          self.assertRaises(LookupError, tostring, a,
    3146                            encoding='Invalid Encoding')
    3147
    3148 -    def test_encoding_tostring_sub(self):
    3149          Element = self.etree.Element
    3150          SubElement = self.etree.SubElement
    3151          tostring = self.etree.tostring
    3152
    3153          a = Element('a')
    3154          b = SubElement(a, 'b')
    3155          b.text = _str('Søk på nettet')
    3156          self.assertEqual(_str('<b>Søk på nettet</b>').encode('UTF-8'),
    3157                           tostring(b, encoding='utf-8'))
    3158
    3159 -    def test_encoding_tostring_sub_tail(self):
    3160          Element = self.etree.Element
    3161          SubElement = self.etree.SubElement
    3162          tostring = self.etree.tostring
    3163
    3164          a = Element('a')
    3165          b = SubElement(a, 'b')
    3166          b.text = _str('Søk på nettet')
    3167          b.tail = _str('Søk')
    3168          self.assertEqual(_str('<b>Søk på nettet</b>Søk').encode('UTF-8'),
    3169                           tostring(b, encoding='utf-8'))
    3170
    3171 -    def test_encoding_tostring_default_encoding(self):
    3172          Element = self.etree.Element
    3173          SubElement = self.etree.SubElement
    3174          tostring = self.etree.tostring
    3175
    3176          a = Element('a')
    3177          a.text = _str('Søk på nettet')
    3178
    3179          expected = _bytes('<a>S&#248;k p&#229; nettet</a>')
    3180          self.assertEqual(
    3181              expected,
    3182              tostring(a))
    3183
    3184 -    def test_encoding_sub_tostring_default_encoding(self):
    3185          Element = self.etree.Element
    3186          SubElement = self.etree.SubElement
    3187          tostring = self.etree.tostring
    3188
    3189          a = Element('a')
    3190          b = SubElement(a, 'b')
    3191          b.text = _str('Søk på nettet')
    3192
    3193          expected = _bytes('<b>S&#248;k p&#229; nettet</b>')
    3194          self.assertEqual(
    3195              expected,
    3196              tostring(b))
    3197
    3198 -    def test_encoding_8bit_xml(self):
    3199          utext = _str('Søk på nettet')
    3200          uxml = _str('<p>%s</p>') % utext
    3201          prologue = _bytes('<?xml version="1.0" encoding="iso-8859-1" ?>')
    3202          isoxml = prologue + uxml.encode('iso-8859-1')
    3203          tree = self.etree.XML(isoxml)
    3204          self.assertEqual(utext, tree.text)
    3205
    3206 -    def test_encoding_utf8_bom(self):
    3207          utext = _str('Søk på nettet')
    3208          uxml = (_str('<?xml version="1.0" encoding="UTF-8"?>') +
    3209                  _str('<p>%s</p>') % utext)
    3210          bom = _bytes('\\xEF\\xBB\\xBF').decode("unicode_escape").encode("latin1")
    3211          xml = bom + uxml.encode("utf-8")
    3212          tree = etree.XML(xml)
    3213          self.assertEqual(utext, tree.text)
    3214
    3215 -    def test_encoding_8bit_parse_stringio(self):
    3216          utext = _str('Søk på nettet')
    3217          uxml = _str('<p>%s</p>') % utext
    3218          prologue = _bytes('<?xml version="1.0" encoding="iso-8859-1" ?>')
    3219          isoxml = prologue + uxml.encode('iso-8859-1')
    3220          el = self.etree.parse(BytesIO(isoxml)).getroot()
    3221          self.assertEqual(utext, el.text)
    3222
    3223 -    def test_deepcopy_elementtree(self):
    3224          Element = self.etree.Element
    3225          ElementTree = self.etree.ElementTree
    3226
    3227          a = Element('a')
    3228          a.text = "Foo"
    3229          atree = ElementTree(a)
    3230
    3231          btree = copy.deepcopy(atree)
    3232          self.assertEqual("Foo", atree.getroot().text)
    3233          self.assertEqual("Foo", btree.getroot().text)
    3234          self.assertFalse(btree is atree)
    3235          self.assertFalse(btree.getroot() is atree.getroot())
    3236
    3237 -    def test_deepcopy(self):
    3238          Element = self.etree.Element
    3239
    3240          a = Element('a')
    3241          a.text = 'Foo'
    3242
    3243          b = copy.deepcopy(a)
    3244          self.assertEqual('Foo', b.text)
    3245
    3246          b.text = 'Bar'
    3247          self.assertEqual('Bar', b.text)
    3248          self.assertEqual('Foo', a.text)
    3249
    3250          del a
    3251          self.assertEqual('Bar', b.text)
    3252
    3253 -    def test_deepcopy_tail(self):
    3254          Element = self.etree.Element
    3255
    3256          a = Element('a')
    3257          a.tail = 'Foo'
    3258
    3259          b = copy.deepcopy(a)
    3260          self.assertEqual('Foo', b.tail)
    3261
    3262          b.tail = 'Bar'
    3263          self.assertEqual('Bar', b.tail)
    3264          self.assertEqual('Foo', a.tail)
    3265
    3266          del a
    3267          self.assertEqual('Bar', b.tail)
    3268
    3269 -    def test_deepcopy_subelement(self):
    3270          Element = self.etree.Element
    3271          SubElement = self.etree.SubElement
    3272
    3273          root = Element('root')
    3274          a = SubElement(root, 'a')
    3275          a.text = 'FooText'
    3276          a.tail = 'FooTail'
    3277
    3278          b = copy.deepcopy(a)
    3279          self.assertEqual('FooText', b.text)
    3280          self.assertEqual('FooTail', b.tail)
    3281
    3282          b.text = 'BarText'
    3283          b.tail = 'BarTail'
    3284          self.assertEqual('BarTail', b.tail)
    3285          self.assertEqual('FooTail', a.tail)
    3286          self.assertEqual('BarText', b.text)
    3287          self.assertEqual('FooText', a.text)
    3288
    3289          del a
    3290          self.assertEqual('BarTail', b.tail)
    3291          self.assertEqual('BarText', b.text)
    3292
    3293 -    def test_deepcopy_namespaces(self):
    3294          root = self.etree.XML(_bytes('''<doc xmlns="dns" xmlns:t="tns">
    3295          <parent><node t:foo="bar" /></parent>
    3296          </doc>'''))
    3297          self.assertEqual(
    3298              root[0][0].get('{tns}foo'),
    3299              copy.deepcopy(root[0])[0].get('{tns}foo') )
    3300          self.assertEqual(
    3301              root[0][0].get('{tns}foo'),
    3302              copy.deepcopy(root[0][0]).get('{tns}foo') )
    3303
    3304 -    def test_deepcopy_append(self):
    3305          # previously caused a crash
    3306          Element = self.etree.Element
    3307          tostring = self.etree.tostring
    3308
    3309          a = Element('a')
    3310          b = copy.deepcopy(a)
    3311          a.append( Element('C') )
    3312          b.append( Element('X') )
    3313
    3314          self.assertEqual(_bytes('<a><C/></a>'),
    3315                            tostring(a).replace(_bytes(' '), _bytes('')))
    3316          self.assertEqual(_bytes('<a><X/></a>'),
    3317                            tostring(b).replace(_bytes(' '), _bytes('')))
    3318
    3319 -    def test_deepcopy_comment(self):
    3320          # previously caused a crash
    3321          # not supported by ET < 1.3!
    3322          Comment = self.etree.Comment
    3323
    3324          a = Comment("ONE")
    3325          b = copy.deepcopy(a)
    3326          b.text = "ANOTHER"
    3327
    3328          self.assertEqual('ONE',     a.text)
    3329          self.assertEqual('ANOTHER', b.text)
    3330
    3331 -    def test_shallowcopy(self):
    3332          Element = self.etree.Element
    3333
    3334          a = Element('a')
    3335          a.text = 'Foo'
    3336
    3337          b = copy.copy(a)
    3338          self.assertEqual('Foo', b.text)
    3339
    3340          b.text = 'Bar'
    3341          self.assertEqual('Bar', b.text)
    3342          self.assertEqual('Foo', a.text)
    3343          # XXX ElementTree will share nodes, but lxml.etree won't..
    3344
    3345 -    def test_shallowcopy_elementtree(self):
    3346          Element = self.etree.Element
    3347          ElementTree = self.etree.ElementTree
    3348
    3349          a = Element('a')
    3350          a.text = 'Foo'
    3351          atree = ElementTree(a)
    3352
    3353          btree = copy.copy(atree)
    3354          self.assertFalse(btree is atree)
    3355          self.assertTrue(btree.getroot() is atree.getroot())
    3356          self.assertEqual('Foo', atree.getroot().text)
    3357
    3358 -    def _test_element_boolean(self):
    3359          # deprecated as of ET 1.3/lxml 2.0
    3360          etree = self.etree
    3361          e = etree.Element('foo')
    3362          self.assertEqual(False, bool(e))
    3363          etree.SubElement(e, 'bar')
    3364          self.assertEqual(True, bool(e))
    3365          e = etree.Element('foo')
    3366          e.text = 'hey'
    3367          self.assertEqual(False, bool(e))
    3368          e = etree.Element('foo')
    3369          e.tail = 'bar'
    3370          self.assertEqual(False, bool(e))
    3371          e = etree.Element('foo')
    3372          e.set('bar', 'Bar')
    3373          self.assertEqual(False, bool(e))
    3374
    3375 -    def test_multiple_elementrees(self):
    3376          etree = self.etree
    3377
    3378          a = etree.Element('a')
    3379          b = etree.SubElement(a, 'b')
    3380
    3381          t = etree.ElementTree(a)
    3382          self.assertEqual(self._rootstring(t), _bytes('<a><b/></a>'))
    3383
    3384          t1 = etree.ElementTree(a)
    3385          self.assertEqual(self._rootstring(t1), _bytes('<a><b/></a>'))
    3386          self.assertEqual(self._rootstring(t),  _bytes('<a><b/></a>'))
    3387
    3388          t2 = etree.ElementTree(b)
    3389          self.assertEqual(self._rootstring(t2), _bytes('<b/>'))
    3390          self.assertEqual(self._rootstring(t1), _bytes('<a><b/></a>'))
    3391          self.assertEqual(self._rootstring(t),  _bytes('<a><b/></a>'))
    3392
    3393 -    def test_qname(self):
    3394          etree = self.etree
    3395          qname = etree.QName('myns', 'a')
    3396          a1 = etree.Element(qname)
    3397          a2 = etree.SubElement(a1, qname)
    3398          self.assertEqual(a1.tag, "{myns}a")
    3399          self.assertEqual(a2.tag, "{myns}a")
    3400
    3401 -    def test_qname_cmp(self):
    3402          etree = self.etree
    3403          qname1 = etree.QName('myns', 'a')
    3404          qname2 = etree.QName('myns', 'a')
    3405          self.assertEqual(qname1, "{myns}a")
    3406          self.assertEqual("{myns}a", qname2)
    3407          self.assertEqual(qname1, qname1)
    3408          self.assertEqual(qname1, qname2)
    3409
    3410 -    def test_qname_attribute_getset(self):
    3411          etree = self.etree
    3412          qname = etree.QName('myns', 'a')
    3413
    3414          a = etree.Element(qname)
    3415          a.set(qname, "value")
    3416
    3417          self.assertEqual(a.get(qname), "value")
    3418          self.assertEqual(a.get("{myns}a"), "value")
    3419
    3420 -    def test_qname_attrib(self):
    3421          etree = self.etree
    3422          qname = etree.QName('myns', 'a')
    3423
    3424          a = etree.Element(qname)
    3425          a.attrib[qname] = "value"
    3426
    3427          self.assertEqual(a.attrib[qname], "value")
    3428          self.assertEqual(a.attrib.get(qname), "value")
    3429
    3430          self.assertEqual(a.attrib["{myns}a"], "value")
    3431          self.assertEqual(a.attrib.get("{myns}a"), "value")
    3432
    3433 -    def test_qname_attribute_resolve(self):
    3434          etree = self.etree
    3435          qname = etree.QName('http://myns', 'a')
    3436          a = etree.Element(qname)
    3437          a.set(qname, qname)
    3438
    3439          self.assertXML(
    3440              _bytes('<ns0:a xmlns:ns0="http://myns" ns0:a="ns0:a"></ns0:a>'),
    3441              a)
    3442
    3443 -    def test_qname_attribute_resolve_new(self):
    3444          etree = self.etree
    3445          qname = etree.QName('http://myns', 'a')
    3446          a = etree.Element('a')
    3447          a.set('a', qname)
    3448
    3449          self.assertXML(
    3450              _bytes('<a xmlns:ns0="http://myns" a="ns0:a"></a>'),
    3451              a)
    3452
    3453 -    def test_qname_attrib_resolve(self):
    3454          etree = self.etree
    3455          qname = etree.QName('http://myns', 'a')
    3456          a = etree.Element(qname)
    3457          a.attrib[qname] = qname
    3458
    3459          self.assertXML(
    3460              _bytes('<ns0:a xmlns:ns0="http://myns" ns0:a="ns0:a"></ns0:a>'),
    3461              a)
    3462
    3463 -    def test_parser_version(self):
    3464          etree = self.etree
    3465          parser = etree.XMLParser()
    3466          if hasattr(parser, "version"):
    3467              # ElementTree 1.3+, cET
    3468              self.assertTrue(re.match("[^ ]+ [0-9.]+", parser.version))
    3469
    3470      # feed parser interface
    3471
    3472 -    def test_feed_parser_bytes(self):
    3473          parser = self.XMLParser()
    3474
    3475          parser.feed(_bytes('<?xml version='))
    3476          parser.feed(_bytes('"1.0"?><ro'))
    3477          parser.feed(_bytes('ot><'))
    3478          parser.feed(_bytes('a test="works"/'))
    3479          parser.feed(_bytes('></root'))
    3480          parser.feed(_bytes('>'))
    3481
    3482          root = parser.close()
    3483
    3484          self.assertEqual(root.tag, "root")
    3485          self.assertEqual(root[0].tag, "a")
    3486          self.assertEqual(root[0].get("test"), "works")
    3487
    3488 -    def test_feed_parser_unicode(self):
    3489          parser = self.XMLParser()
    3490
    3491          parser.feed(_str('<ro'))
    3492          parser.feed(_str('ot><'))
    3493          parser.feed(_str('a test="works"/'))
    3494          parser.feed(_str('></root'))
    3495          parser.feed(_str('>'))
    3496
    3497          root = parser.close()
    3498
    3499          self.assertEqual(root.tag, "root")
    3500          self.assertEqual(root[0].tag, "a")
    3501          self.assertEqual(root[0].get("test"), "works")
    3502
    3503      required_versions_ET['test_feed_parser_error_close_empty'] = (1,3)
    3504 -    def test_feed_parser_error_close_empty(self):
    3505          ParseError = self.etree.ParseError
    3506          parser = self.XMLParser()
    3507          self.assertRaises(ParseError, parser.close)
    3508
    3509      required_versions_ET['test_feed_parser_error_close_incomplete'] = (1,3)
    3510 -    def test_feed_parser_error_close_incomplete(self):
    3511          ParseError = self.etree.ParseError
    3512          parser = self.XMLParser()
    3513
    3514          parser.feed('<?xml version=')
    3515          parser.feed('"1.0"?><ro')
    3516
    3517          self.assertRaises(ParseError, parser.close)
    3518
    3519      required_versions_ET['test_feed_parser_error_broken'] = (1,3)
    3520 -    def test_feed_parser_error_broken(self):
    3521          ParseError = self.etree.ParseError
    3522          parser = self.XMLParser()
    3523
    3524          parser.feed('<?xml version=')
    3525          parser.feed('"1.0"?><ro')
    3526          try:
    3527              parser.feed('<><><><><><><')
    3528          except ParseError:
    3529              # can raise, but not required before close()
    3530              pass
    3531
    3532          self.assertRaises(ParseError, parser.close)
    3533
    3534      required_versions_ET['test_feed_parser_error_position'] = (1,3)
    3535 -    def test_feed_parser_error_position(self):
    3536          ParseError = self.etree.ParseError
    3537          parser = self.XMLParser()
    3538          try:
    3539              parser.close()
    3540          except ParseError:
    3541              e = sys.exc_info()[1]
    3542              self.assertNotEqual(None, e.code)
    3543              self.assertNotEqual(0, e.code)
    3544              self.assertTrue(isinstance(e.position, tuple))
    3545              self.assertTrue(e.position >= (0, 0))
    3546
    3547      # parser target interface
    3548
    3549      required_versions_ET['test_parser_target_property'] = (1,3)
    3550 -    def test_parser_target_property(self):
    3551          class Target(object):
    3552              pass
    3553
    3554          target = Target()
    3555          parser = self.XMLParser(target=target)
    3556
    3557          self.assertEqual(target, parser.target)
    3558
    3559 -    def test_parser_target_tag(self):
    3560          assertEqual = self.assertEqual
    3561          assertFalse  = self.assertFalse
    3562
    3563          events = []
    3564          class Target(object):
    3565              def start(self, tag, attrib):
    3566                  events.append("start")
    3567                  assertFalse(attrib)
    3568                  assertEqual("TAG", tag)
    3569              def end(self, tag):
    3570                  events.append("end")
    3571                  assertEqual("TAG", tag)
    3572              def close(self):
    3573                  return "DONE"
    3574
    3575          parser = self.XMLParser(target=Target())
    3576
    3577          parser.feed("<TAG/>")
    3578          done = parser.close()
    3579
    3580          self.assertEqual("DONE", done)
    3581          self.assertEqual(["start", "end"], events)
    3582
    3583 -    def test_parser_target_error_in_start(self):
    3584          assertEqual = self.assertEqual
    3585
    3586          events = []
    3587          class Target(object):
    3588              def start(self, tag, attrib):
    3589                  events.append("start")
    3590                  assertEqual("TAG", tag)
    3591                  raise ValueError("TEST")
    3592              def end(self, tag):
    3593                  events.append("end")
    3594                  assertEqual("TAG", tag)
    3595              def close(self):
    3596                  return "DONE"
    3597
    3598          parser = self.XMLParser(target=Target())
    3599
    3600          try:
    3601              parser.feed("<TAG/>")
    3602          except ValueError:
    3603              self.assertTrue('TEST' in str(sys.exc_info()[1]))
    3604          else:
    3605              self.assertTrue(False)
    3606          if 'lxml' in self.etree.__name__:
    3607              self.assertEqual(["start"], events)
    3608          else:
    3609              # cElementTree calls end() as well
    3610              self.assertTrue("start" in events)
    3611
    3612 -    def test_parser_target_error_in_end(self):
    3613          assertEqual = self.assertEqual
    3614
    3615          events = []
    3616          class Target(object):
    3617              def start(self, tag, attrib):
    3618                  events.append("start")
    3619                  assertEqual("TAG", tag)
    3620              def end(self, tag):
    3621                  events.append("end")
    3622                  assertEqual("TAG", tag)
    3623                  raise ValueError("TEST")
    3624              def close(self):
    3625                  return "DONE"
    3626
    3627          parser = self.XMLParser(target=Target())
    3628
    3629          try:
    3630              parser.feed("<TAG/>")
    3631          except ValueError:
    3632              self.assertTrue('TEST' in str(sys.exc_info()[1]))
    3633          else:
    3634              self.assertTrue(False)
    3635          self.assertEqual(["start", "end"], events)
    3636
    3637 -    def test_parser_target_error_in_close(self):
    3638          assertEqual = self.assertEqual
    3639
    3640          events = []
    3641          class Target(object):
    3642              def start(self, tag, attrib):
    3643                  events.append("start")
    3644                  assertEqual("TAG", tag)
    3645              def end(self, tag):
    3646                  events.append("end")
    3647                  assertEqual("TAG", tag)
    3648              def close(self):
    3649                  raise ValueError("TEST")
    3650
    3651          parser = self.XMLParser(target=Target())
    3652
    3653          try:
    3654              parser.feed("<TAG/>")
    3655              parser.close()
    3656          except ValueError:
    3657              self.assertTrue('TEST' in str(sys.exc_info()[1]))
    3658          else:
    3659              self.assertTrue(False)
    3660          self.assertEqual(["start", "end"], events)
    3661
    3662 -    def test_parser_target_error_in_start_and_close(self):
    3663          assertEqual = self.assertEqual
    3664
    3665          events = []
    3666          class Target(object):
    3667              def start(self, tag, attrib):
    3668                  events.append("start")
    3669                  assertEqual("TAG", tag)
    3670                  raise IndexError("TEST-IE")
    3671              def end(self, tag):
    3672                  events.append("end")
    3673                  assertEqual("TAG", tag)
    3674              def close(self):
    3675                  raise ValueError("TEST-VE")
    3676
    3677          parser = self.XMLParser(target=Target())
    3678
    3679          try:
    3680              parser.feed("<TAG/>")
    3681              parser.close()
    3682          except IndexError:
    3683              if 'lxml' in self.etree.__name__:
    3684                  # we try not to swallow the initial exception in Py2
    3685                  self.assertTrue(sys.version_info[0] < 3)
    3686              self.assertTrue('TEST-IE' in str(sys.exc_info()[1]))
    3687          except ValueError:
    3688              if 'lxml' in self.etree.__name__:
    3689                  self.assertTrue(sys.version_info[0] >= 3)
    3690              self.assertTrue('TEST-VE' in str(sys.exc_info()[1]))
    3691          else:
    3692              self.assertTrue(False)
    3693
    3694          if 'lxml' in self.etree.__name__:
    3695              self.assertEqual(["start"], events)
    3696          else:
    3697              # cElementTree calls end() as well
    3698              self.assertTrue("start" in events)
    3699
    3700 -    def test_elementtree_parser_target(self):
    3701          assertEqual = self.assertEqual
    3702          assertFalse  = self.assertFalse
    3703          Element = self.etree.Element
    3704
    3705          events = []
    3706          class Target(object):
    3707              def start(self, tag, attrib):
    3708                  events.append("start")
    3709                  assertFalse(attrib)
    3710                  assertEqual("TAG", tag)
    3711              def end(self, tag):
    3712                  events.append("end")
    3713                  assertEqual("TAG", tag)
    3714              def close(self):
    3715                  return Element("DONE")
    3716
    3717          parser = self.XMLParser(target=Target())
    3718          tree = self.etree.ElementTree()
    3719          tree.parse(BytesIO("<TAG/>"), parser=parser)
    3720
    3721          self.assertEqual("DONE", tree.getroot().tag)
    3722          self.assertEqual(["start", "end"], events)
    3723
    3724 -    def test_parser_target_attrib(self):
    3725          assertEqual = self.assertEqual
    3726
    3727          events = []
    3728          class Target(object):
    3729              def start(self, tag, attrib):
    3730                  events.append("start-" + tag)
    3731                  for name, value in attrib.items():
    3732                      assertEqual(tag + name, value)
    3733              def end(self, tag):
    3734                  events.append("end-" + tag)
    3735              def close(self):
    3736                  return "DONE"
    3737
    3738          parser = self.XMLParser(target=Target())
    3739
    3740          parser.feed('<root a="roota" b="rootb"><sub c="subc"/></root>')
    3741          done = parser.close()
    3742
    3743          self.assertEqual("DONE", done)
    3744          self.assertEqual(["start-root", "start-sub", "end-sub", "end-root"],
    3745                            events)
    3746
    3747 -    def test_parser_target_data(self):
    3748          events = []
    3749          class Target(object):
    3750              def start(self, tag, attrib):
    3751                  events.append("start-" + tag)
    3752              def end(self, tag):
    3753                  events.append("end-" + tag)
    3754              def data(self, data):
    3755                  events.append("data-" + data)
    3756              def close(self):
    3757                  return "DONE"
    3758
    3759          parser = self.XMLParser(target=Target())
    3760
    3761          parser.feed('<root>A<sub/>B</root>')
    3762          done = parser.close()
    3763
    3764          self.assertEqual("DONE", done)
    3765          self.assertEqual(["start-root", "data-A", "start-sub",
    3766                             "end-sub", "data-B", "end-root"],
    3767                            events)
    3768
    3769 -    def test_parser_target_entity(self):
    3770          events = []
    3771          class Target(object):
    3772              def __init__(self):
    3773                  self._data = []
    3774              def _flush_data(self):
    3775                  if self._data:
    3776                      events.append("data-" + ''.join(self._data))
    3777                      del self._data[:]
    3778              def start(self, tag, attrib):
    3779                  self._flush_data()
    3780                  events.append("start-" + tag)
    3781              def end(self, tag):
    3782                  self._flush_data()
    3783                  events.append("end-" + tag)
    3784              def data(self, data):
    3785                  self._data.append(data)
    3786              def close(self):
    3787                  self._flush_data()
    3788                  return "DONE"
    3789
    3790          parser = self.XMLParser(target=Target())
    3791
    3792          dtd = '''
    3793              <!DOCTYPE root [
    3794              <!ELEMENT root (sub*)>
    3795              <!ELEMENT sub (#PCDATA)>
    3796              <!ENTITY ent "an entity">
    3797          ]>
    3798          '''
    3799          parser.feed(dtd+'<root><sub/><sub>this is &ent;</sub><sub/></root>')
    3800          done = parser.close()
    3801
    3802          self.assertEqual("DONE", done)
    3803          self.assertEqual(["start-root", "start-sub", "end-sub", "start-sub",
    3804                             "data-this is an entity",
    3805                             "end-sub", "start-sub", "end-sub", "end-root"],
    3806                            events)
    3807
    3808      required_versions_ET['test_parser_target_entity_unknown'] = (1,3)
    3809 -    def test_parser_target_entity_unknown(self):
    3810          events = []
    3811          class Target(object):
    3812              def __init__(self):
    3813                  self._data = []
    3814              def _flush_data(self):
    3815                  if self._data:
    3816                      events.append("data-" + ''.join(self._data))
    3817                      del self._data[:]
    3818              def start(self, tag, attrib):
    3819                  self._flush_data()
    3820                  events.append("start-" + tag)
    3821              def end(self, tag):
    3822                  self._flush_data()
    3823                  events.append("end-" + tag)
    3824              def data(self, data):
    3825                  self._data.append(data)
    3826              def close(self):
    3827                  self._flush_data()
    3828                  return "DONE"
    3829
    3830          parser = self.XMLParser(target=Target())
    3831
    3832          def feed():
    3833              parser.feed('<root><sub/><sub>some &ent;</sub><sub/></root>')
    3834              parser.close()
    3835
    3836          self.assertRaises(self.etree.ParseError, feed)
    3837
    3838 -    def test_treebuilder(self):
    3839          builder = self.etree.TreeBuilder()
    3840          el = builder.start("root", {'a':'A', 'b':'B'})
    3841          self.assertEqual("root", el.tag)
    3842          self.assertEqual({'a':'A', 'b':'B'}, el.attrib)
    3843          builder.data("ROOTTEXT")
    3844          el = builder.start("child", {'x':'X', 'y':'Y'})
    3845          self.assertEqual("child", el.tag)
    3846          self.assertEqual({'x':'X', 'y':'Y'}, el.attrib)
    3847          builder.data("CHILDTEXT")
    3848          el = builder.end("child")
    3849          self.assertEqual("child", el.tag)
    3850          self.assertEqual({'x':'X', 'y':'Y'}, el.attrib)
    3851          self.assertEqual("CHILDTEXT", el.text)
    3852          self.assertEqual(None, el.tail)
    3853          builder.data("CHILDTAIL")
    3854          root = builder.end("root")
    3855
    3856          self.assertEqual("root", root.tag)
    3857          self.assertEqual("ROOTTEXT", root.text)
    3858          self.assertEqual("CHILDTEXT", root[0].text)
    3859          self.assertEqual("CHILDTAIL", root[0].tail)
    3860
    3861 -    def test_treebuilder_target(self):
    3862          parser = self.XMLParser(target=self.etree.TreeBuilder())
    3863          parser.feed('<root>ROOTTEXT<child>CHILDTEXT</child>CHILDTAIL</root>')
    3864          root = parser.close()
    3865
    3866          self.assertEqual("root", root.tag)
    3867          self.assertEqual("ROOTTEXT", root.text)
    3868          self.assertEqual("CHILDTEXT", root[0].text)
    3869          self.assertEqual("CHILDTAIL", root[0].tail)
    3870
    3871      # helper methods
    3872
    3873 -    def _writeElement(self, element, encoding='us-ascii'):
    3874          """Write out element for comparison.
    3875          """
    3876          data = self.etree.tostring(element, encoding=encoding)
    3877          return canonicalize(data)
    3878
    3879 -    def _writeElementFile(self, element, encoding='us-ascii'):
    3880          """Write out element for comparison, using real file.
    3881          """
    3882          ElementTree = self.etree.ElementTree
    3883          handle, filename = tempfile.mkstemp()
    3884          try:
    3885              f = open(filename, 'wb')
    3886              tree = ElementTree(element=element)
    3887              tree.write(f, encoding=encoding)
    3888              f.close()
    3889              f = open(filename, 'rb')
    3890              data = f.read()
    3891              f.close()
    3892          finally:
    3893              os.close(handle)
    3894              os.remove(filename)
    3895          return canonicalize(data)
    3896
    3897 -    def assertXML(self, expected, element, encoding='us-ascii'):
    3898          """Writes element out and checks whether it is expected.
    3899
    3900          Does this two ways; once using BytesIO, once using a real file.
    3901          """
    3902          if isinstance(expected, unicode):
    3903              expected = expected.encode(encoding)
    3904          self.assertEqual(expected, self._writeElement(element, encoding))
    3905          self.assertEqual(expected, self._writeElementFile(element, encoding))
    3906
    3907 -    def assertEncodingDeclaration(self, result, encoding):
    3908          "Checks if the result XML byte string specifies the encoding."
    3909          enc_re = r"<\?xml[^>]+ encoding=[\"']([^\"']+)[\"']"
    3910          if isinstance(result, str):
    3911              has_encoding = re.compile(enc_re).match
    3912          else:
    3913              has_encoding = re.compile(_bytes(enc_re)).match
    3914          self.assertTrue(has_encoding(result))
    3915          result_encoding = has_encoding(result).group(1)
    3916          self.assertEqual(result_encoding.upper(), encoding.upper())
    3917
    3918 -    def _rootstring(self, tree):
    3919          return self.etree.tostring(tree.getroot()).replace(
    3920              _bytes(' '), _bytes('')).replace(_bytes('\n'), _bytes(''))
    3921
    3922 -    def _check_element_tree(self, tree):
    3923          self._check_element(tree.getroot())
    3924
    3925 -    def _check_element(self, element):
    3926          self.assertTrue(hasattr(element, 'tag'))
    3927          self.assertTrue(hasattr(element, 'attrib'))
    3928          self.assertTrue(hasattr(element, 'text'))
    3929          self.assertTrue(hasattr(element, 'tail'))
    3930          self._check_string(element.tag)
    3931          self._check_mapping(element.attrib)
    3932          if element.text != None:
    3933              self._check_string(element.text)
    3934          if element.tail != None:
    3935              self._check_string(element.tail)
    3936
    3937 -    def _check_string(self, string):
    3938          len(string)
    3939          for char in string:
    3940              self.assertEqual(1, len(char))
    3941          new_string = string + ""
    3942          new_string = string + " "
    3943          string[:0]
    3944
    3945 -    def _check_mapping(self, mapping):
    3946          len(mapping)
    3947          keys = mapping.keys()
    3948          values = mapping.values()
    3949          items = mapping.items()
    3950          for key in keys:
    3951              item = mapping[key]
    3952          mapping["key"] = "value"
    3953          self.assertEqual("value", mapping["key"])
    3954
    3955
    3956 -class _XMLPullParserTest(unittest.TestCase):
    3957      etree = None
    3958
    3959 -    def _feed(self, parser, data, chunk_size=None):
    3960          if chunk_size is None:
    3961              parser.feed(data)
    3962          else:
    3963              for i in range(0, len(data), chunk_size):
    3964                  parser.feed(data[i:i+chunk_size])
    3965
    3966 -    def _close_and_return_root(self, parser):
    3967          if 'ElementTree' in self.etree.__name__:
    3968              # ElementTree's API is a bit unwieldy in Py3.4
    3969              root = parser._close_and_return_root()
    3970          else:
    3971              root = parser.close()
    3972          return root
    3973
    3974 -    def assert_event_tags(self, parser, expected):
    3975          events = parser.read_events()
    3976          self.assertEqual([(action, elem.tag) for action, elem in events],
    3977                           expected)
    3978
    3979 -    def test_simple_xml(self):
    3980          for chunk_size in (None, 1, 5):
    3981              #with self.subTest(chunk_size=chunk_size):
    3982                  parser = self.etree.XMLPullParser()
    3983                  self.assert_event_tags(parser, [])
    3984                  self._feed(parser, "<!-- comment -->\n", chunk_size)
    3985                  self.assert_event_tags(parser, [])
    3986                  self._feed(parser,
    3987                             "<root>\n  <element key='value'>text</element",
    3988                             chunk_size)
    3989                  self.assert_event_tags(parser, [])
    3990                  self._feed(parser, ">\n", chunk_size)
    3991                  self.assert_event_tags(parser, [('end', 'element')])
    3992                  self._feed(parser, "<element>text</element>tail\n", chunk_size)
    3993                  self._feed(parser, "<empty-element/>\n", chunk_size)
    3994                  self.assert_event_tags(parser, [
    3995                      ('end', 'element'),
    3996                      ('end', 'empty-element'),
    3997                      ])
    3998                  self._feed(parser, "</root>\n", chunk_size)
    3999                  self.assert_event_tags(parser, [('end', 'root')])
    4000                  root = self._close_and_return_root(parser)
    4001                  self.assertEqual(root.tag, 'root')
    4002
    4003 -    def test_feed_while_iterating(self):
    4004          parser = self.etree.XMLPullParser()
    4005          it = parser.read_events()
    4006          self._feed(parser, "<root>\n  <element key='value'>text</element>\n")
    4007          action, elem = next(it)
    4008          self.assertEqual((action, elem.tag), ('end', 'element'))
    4009          self._feed(parser, "</root>\n")
    4010          action, elem = next(it)
    4011          self.assertEqual((action, elem.tag), ('end', 'root'))
    4012          try:
    4013              next(it)
    4014          except StopIteration:
    4015              self.assertTrue(True)
    4016          else:
    4017              self.assertTrue(False)
    4018
    4019 -    def test_simple_xml_with_ns(self):
    4020          parser = self.etree.XMLPullParser()
    4021          self.assert_event_tags(parser, [])
    4022          self._feed(parser, "<!-- comment -->\n")
    4023          self.assert_event_tags(parser, [])
    4024          self._feed(parser, "<root xmlns='namespace'>\n")
    4025          self.assert_event_tags(parser, [])
    4026          self._feed(parser, "<element key='value'>text</element")
    4027          self.assert_event_tags(parser, [])
    4028          self._feed(parser, ">\n")
    4029          self.assert_event_tags(parser, [('end', '{namespace}element')])
    4030          self._feed(parser, "<element>text</element>tail\n")
    4031          self._feed(parser, "<empty-element/>\n")
    4032          self.assert_event_tags(parser, [
    4033              ('end', '{namespace}element'),
    4034              ('end', '{namespace}empty-element'),
    4035              ])
    4036          self._feed(parser, "</root>\n")
    4037          self.assert_event_tags(parser, [('end', '{namespace}root')])
    4038          root = self._close_and_return_root(parser)
    4039          self.assertEqual(root.tag, '{namespace}root')
    4040
    4041 -    def test_ns_events(self):
    4042          parser = self.etree.XMLPullParser(events=('start-ns', 'end-ns'))
    4043          self._feed(parser, "<!-- comment -->\n")
    4044          self._feed(parser, "<root xmlns='namespace'>\n")
    4045          self.assertEqual(
    4046              list(parser.read_events()),
    4047              [('start-ns', ('', 'namespace'))])
    4048          self._feed(parser, "<element key='value'>text</element")
    4049          self._feed(parser, ">\n")
    4050          self._feed(parser, "<element>text</element>tail\n")
    4051          self._feed(parser, "<empty-element/>\n")
    4052          self._feed(parser, "</root>\n")
    4053          self.assertEqual(list(parser.read_events()), [('end-ns', None)])
    4054          parser.close()
    4055
    4056 -    def test_events(self):
    4057          parser = self.etree.XMLPullParser(events=())
    4058          self._feed(parser, "<root/>\n")
    4059          self.assert_event_tags(parser, [])
    4060
    4061          parser = self.etree.XMLPullParser(events=('start', 'end'))
    4062          self._feed(parser, "<!-- comment -->\n")
    4063          self.assert_event_tags(parser, [])
    4064          self._feed(parser, "<root>\n")
    4065          self.assert_event_tags(parser, [('start', 'root')])
    4066          self._feed(parser, "<element key='value'>text</element")
    4067          self.assert_event_tags(parser, [('start', 'element')])
    4068          self._feed(parser, ">\n")
    4069          self.assert_event_tags(parser, [('end', 'element')])
    4070          self._feed(parser,
    4071                     "<element xmlns='foo'>text<empty-element/></element>tail\n")
    4072          self.assert_event_tags(parser, [
    4073              ('start', '{foo}element'),
    4074              ('start', '{foo}empty-element'),
    4075              ('end', '{foo}empty-element'),
    4076              ('end', '{foo}element'),
    4077              ])
    4078          self._feed(parser, "</root>")
    4079          root = self._close_and_return_root(parser)
    4080          self.assert_event_tags(parser, [('end', 'root')])
    4081          self.assertEqual(root.tag, 'root')
    4082
    4083          parser = self.etree.XMLPullParser(events=('start',))
    4084          self._feed(parser, "<!-- comment -->\n")
    4085          self.assert_event_tags(parser, [])
    4086          self._feed(parser, "<root>\n")
    4087          self.assert_event_tags(parser, [('start', 'root')])
    4088          self._feed(parser, "<element key='value'>text</element")
    4089          self.assert_event_tags(parser, [('start', 'element')])
    4090          self._feed(parser, ">\n")
    4091          self.assert_event_tags(parser, [])
    4092          self._feed(parser,
    4093                     "<element xmlns='foo'>text<empty-element/></element>tail\n")
    4094          self.assert_event_tags(parser, [
    4095              ('start', '{foo}element'),
    4096              ('start', '{foo}empty-element'),
    4097              ])
    4098          self._feed(parser, "</root>")
    4099          root = self._close_and_return_root(parser)
    4100          self.assertEqual(root.tag, 'root')
    4101
    4102 -    def test_events_sequence(self):
    4103          # Test that events can be some sequence that's not just a tuple or list
    4104          eventset = set(['end', 'start'])
    4105          parser = self.etree.XMLPullParser(events=eventset)
    4106          self._feed(parser, "<foo>bar</foo>")
    4107          self.assert_event_tags(parser, [('start', 'foo'), ('end', 'foo')])
    4108
    4109          class DummyIter:
    4110              def __init__(self):
    4111                  self.events = iter(['start', 'end', 'start-ns'])
    4112              def __iter__(self):
    4113                  return self
    4114              def __next__(self):
    4115                  return next(self.events)
    4116              next = __next__
    4117
    4118          parser = self.etree.XMLPullParser(events=DummyIter())
    4119          self._feed(parser, "<foo>bar</foo>")
    4120          self.assert_event_tags(parser, [('start', 'foo'), ('end', 'foo')])
    4121
    4122 -    def test_unknown_event(self):
    4123          try:
    4124              self.etree.XMLPullParser(events=('start', 'end', 'bogus'))
    4125          except ValueError:
    4126              self.assertTrue(True)
    4127          else:
    4128              self.assertTrue(False)
    4129
    4130
    4131  if etree:
    4132 -    class ETreeTestCase(_ETreeTestCaseBase):
    4133          etree = etree
    4134
    4135 -    class ETreePullTestCase(_XMLPullParserTest):
    4136          etree = etree
    4137
    4138
    4139  if ElementTree:
    4140 -    class ElementTreeTestCase(_ETreeTestCaseBase):
    4141          etree = ElementTree
    4142
    4143          @classmethod
    4144 -        def setUpClass(cls):
    4145              import warnings
    4146              # ElementTree warns about getiterator() in recent Pythons
    4147              warnings.filterwarnings(
    4148                  'ignore',
    4149                  r'This method will be removed.*\.iter\(\).*instead',
    4150                  PendingDeprecationWarning)
    4151
    4152      filter_by_version(
    4153          ElementTreeTestCase,
    4154          ElementTreeTestCase.required_versions_ET, ET_VERSION)
    4155
    4156      if hasattr(ElementTree, 'XMLPullParser'):
    4157 -        class ElementTreePullTestCase(_XMLPullParserTest):
    4158              etree = ElementTree
    4159      else:
    4160          ElementTreePullTestCase = None
    4161
    4162
    4163  if cElementTree:
    4164 -    class CElementTreeTestCase(_ETreeTestCaseBase):
    4165          etree = cElementTree
    4166
    4167      filter_by_version(
    4168          CElementTreeTestCase,
    4169          CElementTreeTestCase.required_versions_cET, CET_VERSION)
    4170
    4171
    4172 -def test_suite():
    4173      suite = unittest.TestSuite()
    4174      if etree:
    4175          suite.addTests([unittest.makeSuite(ETreeTestCase)])
    4176          suite.addTests([unittest.makeSuite(ETreePullTestCase)])
    4177      if ElementTree:
    4178          suite.addTests([unittest.makeSuite(ElementTreeTestCase)])
    4179          if ElementTreePullTestCase:
    4180              suite.addTests([unittest.makeSuite(ElementTreePullTestCase)])
    4181      if cElementTree:
    4182          suite.addTests([unittest.makeSuite(CElementTreeTestCase)])
    4183      return suite
    4184
    4185  if __name__ == '__main__':
    4186      print('to test use test.py %s' % __file__)
    4187