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