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