lxml.tests.test_elementtree

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

# Source Code for Module lxml.tests.test_elementtree

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