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

# Source Code for Module lxml.tests.test_elementtree

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