lxml.tests.test_objectify

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

# Source Code for Module lxml.tests.test_objectify

       1  # -*- coding: utf-8 -*-
       2
       3  """
       4  Tests specific to the lxml.objectify API
       5  """
       6
       7
       8  import unittest, operator, sys, os.path
       9
      10  this_dir = os.path.dirname(__file__)
      11  if this_dir not in sys.path:
      12      sys.path.insert(0, this_dir) # needed for Py3
      13
      14  from common_imports import etree, HelperTestCase, fileInTestDir
      15  from common_imports import SillyFileLike, canonicalize, doctest, make_doctest
      16  from common_imports import _bytes, _str, StringIO, BytesIO
      17
      18  from lxml import objectify
      19
      20  PYTYPE_NAMESPACE = "http://codespeak.net/lxml/objectify/pytype"
      21  XML_SCHEMA_NS = "http://www.w3.org/2001/XMLSchema"
      22  XML_SCHEMA_INSTANCE_NS = "http://www.w3.org/2001/XMLSchema-instance"
      23  XML_SCHEMA_INSTANCE_TYPE_ATTR = "{%s}type" % XML_SCHEMA_INSTANCE_NS
      24  XML_SCHEMA_NIL_ATTR = "{%s}nil" % XML_SCHEMA_INSTANCE_NS
      25  TREE_PYTYPE = "TREE"
      26  DEFAULT_NSMAP = { "py"  : PYTYPE_NAMESPACE,
      27                    "xsi" : XML_SCHEMA_INSTANCE_NS,
      28                    "xsd" : XML_SCHEMA_NS}
      29
      30  objectclass2xsitype = {
      31      # objectify built-in
      32      objectify.IntElement: ("int", "short", "byte", "unsignedShort",
      33                             "unsignedByte", "integer", "nonPositiveInteger",
      34                             "negativeInteger", "long", "nonNegativeInteger",
      35                             "unsignedLong", "unsignedInt", "positiveInteger",),
      36      objectify.FloatElement: ("float", "double"),
      37      objectify.BoolElement: ("boolean",),
      38      objectify.StringElement: ("string", "normalizedString", "token", "language",
      39                                "Name", "NCName", "ID", "IDREF", "ENTITY",
      40                                "NMTOKEN", ),
      41      # None: xsi:nil="true"
      42      }
      43
      44  xsitype2objclass = dict([ (v, k) for k in objectclass2xsitype
      45                            for v in objectclass2xsitype[k] ])
      46
      47  objectclass2pytype = {
      48      # objectify built-in
      49      objectify.IntElement: "int",
      50      objectify.FloatElement: "float",
      51      objectify.BoolElement: "bool",
      52      objectify.StringElement: "str",
      53      # None: xsi:nil="true"
      54      }
      55
      56  pytype2objclass = dict([ (objectclass2pytype[k], k)
      57                           for k in objectclass2pytype])
      58
      59  xml_str = '''\
      60  <obj:root xmlns:obj="objectified" xmlns:other="otherNS">
      61    <obj:c1 a1="A1" a2="A2" other:a3="A3">
      62      <obj:c2>0</obj:c2>
      63      <obj:c2>1</obj:c2>
      64      <obj:c2>2</obj:c2>
      65      <other:c2>3</other:c2>
      66      <c2>4</c2>
      67    </obj:c1>
      68  </obj:root>'''
      69
      70 -class ObjectifyTestCase(HelperTestCase):
      71      """Test cases for lxml.objectify
      72      """
      73      etree = etree
      74
      75 -    def XML(self, xml):
      76          return self.etree.XML(xml, self.parser)
      77
      78 -    def setUp(self):
      79          super(ObjectifyTestCase, self).setUp()
      80          self.parser = self.etree.XMLParser(remove_blank_text=True)
      81          self.lookup = etree.ElementNamespaceClassLookup(
      82              objectify.ObjectifyElementClassLookup() )
      83          self.parser.set_element_class_lookup(self.lookup)
      84
      85          self.Element = self.parser.makeelement
      86
      87          ns = self.lookup.get_namespace("otherNS")
      88          ns[None] = self.etree.ElementBase
      89
      90          self._orig_types = objectify.getRegisteredTypes()
      91
      92 -    def tearDown(self):
      93          self.lookup.get_namespace("otherNS").clear()
      94          objectify.set_pytype_attribute_tag()
      95          del self.lookup
      96          del self.parser
      97
      98          for pytype in objectify.getRegisteredTypes():
      99              pytype.unregister()
     100          for pytype in self._orig_types:
     101              pytype.register()
     102          del self._orig_types
     103
     104          super(ObjectifyTestCase, self).tearDown()
     105
     106
     107 -    def test_element_nsmap_default(self):
     108          elt = objectify.Element("test")
     109          self.assertEqual(elt.nsmap, DEFAULT_NSMAP)
     110
     111 -    def test_element_nsmap_empty(self):
     112          nsmap = {}
     113          elt = objectify.Element("test", nsmap=nsmap)
     114          self.assertEqual(list(elt.nsmap.values()), [PYTYPE_NAMESPACE])
     115
     116 -    def test_element_nsmap_custom_prefixes(self):
     117          nsmap = {"mypy": PYTYPE_NAMESPACE,
     118                   "myxsi": XML_SCHEMA_INSTANCE_NS,
     119                   "myxsd": XML_SCHEMA_NS}
     120          elt = objectify.Element("test", nsmap=nsmap)
     121          self.assertEqual(elt.nsmap, nsmap)
     122
     123 -    def test_element_nsmap_custom(self):
     124          nsmap = {"my": "someNS",
     125                   "myother": "someOtherNS",
     126                   "myxsd": XML_SCHEMA_NS}
     127          elt = objectify.Element("test", nsmap=nsmap)
     128          self.assertTrue(PYTYPE_NAMESPACE in elt.nsmap.values())
     129          for prefix, ns in nsmap.items():
     130              self.assertTrue(prefix in elt.nsmap)
     131              self.assertEqual(nsmap[prefix], elt.nsmap[prefix])
     132
     133 -    def test_sub_element_nsmap_default(self):
     134          root = objectify.Element("root")
     135          root.sub = objectify.Element("test")
     136          self.assertEqual(root.sub.nsmap, DEFAULT_NSMAP)
     137
     138 -    def test_sub_element_nsmap_empty(self):
     139          root = objectify.Element("root")
     140          nsmap = {}
     141          root.sub = objectify.Element("test", nsmap=nsmap)
     142          self.assertEqual(root.sub.nsmap, DEFAULT_NSMAP)
     143
     144 -    def test_sub_element_nsmap_custom_prefixes(self):
     145          root = objectify.Element("root")
     146          nsmap = {"mypy": PYTYPE_NAMESPACE,
     147                   "myxsi": XML_SCHEMA_INSTANCE_NS,
     148                   "myxsd": XML_SCHEMA_NS}
     149          root.sub = objectify.Element("test", nsmap=nsmap)
     150          self.assertEqual(root.sub.nsmap, DEFAULT_NSMAP)
     151
     152 -    def test_sub_element_nsmap_custom(self):
     153          root = objectify.Element("root")
     154          nsmap = {"my": "someNS",
     155                   "myother": "someOtherNS",
     156                   "myxsd": XML_SCHEMA_NS,}
     157          root.sub = objectify.Element("test", nsmap=nsmap)
     158          expected = nsmap.copy()
     159          del expected["myxsd"]
     160          expected.update(DEFAULT_NSMAP)
     161          self.assertEqual(root.sub.nsmap, expected)
     162
     163 -    def test_data_element_nsmap_default(self):
     164          value = objectify.DataElement("test this")
     165          self.assertEqual(value.nsmap, DEFAULT_NSMAP)
     166
     167 -    def test_data_element_nsmap_empty(self):
     168          nsmap = {}
     169          value = objectify.DataElement("test this", nsmap=nsmap)
     170          self.assertEqual(list(value.nsmap.values()), [PYTYPE_NAMESPACE])
     171
     172 -    def test_data_element_nsmap_custom_prefixes(self):
     173          nsmap = {"mypy": PYTYPE_NAMESPACE,
     174                   "myxsi": XML_SCHEMA_INSTANCE_NS,
     175                   "myxsd": XML_SCHEMA_NS}
     176          value = objectify.DataElement("test this", nsmap=nsmap)
     177          self.assertEqual(value.nsmap, nsmap)
     178
     179 -    def test_data_element_nsmap_custom(self):
     180          nsmap = {"my": "someNS",
     181                   "myother": "someOtherNS",
     182                   "myxsd": XML_SCHEMA_NS,}
     183          value = objectify.DataElement("test", nsmap=nsmap)
     184          self.assertTrue(PYTYPE_NAMESPACE in value.nsmap.values())
     185          for prefix, ns in nsmap.items():
     186              self.assertTrue(prefix in value.nsmap)
     187              self.assertEqual(nsmap[prefix], value.nsmap[prefix])
     188
     189 -    def test_sub_data_element_nsmap_default(self):
     190          root = objectify.Element("root")
     191          root.value = objectify.DataElement("test this")
     192          self.assertEqual(root.value.nsmap, DEFAULT_NSMAP)
     193
     194 -    def test_sub_data_element_nsmap_empty(self):
     195          root = objectify.Element("root")
     196          nsmap = {}
     197          root.value = objectify.DataElement("test this", nsmap=nsmap)
     198          self.assertEqual(root.value.nsmap, DEFAULT_NSMAP)
     199
     200 -    def test_sub_data_element_nsmap_custom_prefixes(self):
     201          root = objectify.Element("root")
     202          nsmap = {"mypy": PYTYPE_NAMESPACE,
     203                   "myxsi": XML_SCHEMA_INSTANCE_NS,
     204                   "myxsd": XML_SCHEMA_NS}
     205          root.value = objectify.DataElement("test this", nsmap=nsmap)
     206          self.assertEqual(root.value.nsmap, DEFAULT_NSMAP)
     207
     208 -    def test_sub_data_element_nsmap_custom(self):
     209          root = objectify.Element("root")
     210          nsmap = {"my": "someNS",
     211                   "myother": "someOtherNS",
     212                   "myxsd": XML_SCHEMA_NS}
     213          root.value = objectify.DataElement("test", nsmap=nsmap)
     214          expected = nsmap.copy()
     215          del expected["myxsd"]
     216          expected.update(DEFAULT_NSMAP)
     217          self.assertEqual(root.value.nsmap, expected)
     218
     219 -    def test_date_element_efactory_text(self):
     220          # ObjectifiedDataElement can also be used as E-Factory
     221          value = objectify.ObjectifiedDataElement('test', 'toast')
     222          self.assertEqual(value.text, 'testtoast')
     223
     224 -    def test_date_element_efactory_tail(self):
     225          # ObjectifiedDataElement can also be used as E-Factory
     226          value = objectify.ObjectifiedElement(objectify.ObjectifiedDataElement(), 'test', 'toast')
     227          self.assertEqual(value.ObjectifiedDataElement.tail, 'testtoast')
     228
     229 -    def test_data_element_attrib_attributes_precedence(self):
     230          # keyword arguments override attrib entries
     231          value = objectify.DataElement(23, _pytype="str", _xsi="foobar",
     232                                        attrib={"gnu": "muh", "cat": "meeow",
     233                                                "dog": "wuff"},
     234                                        bird="tchilp", dog="grrr")
     235          self.assertEqual(value.get("gnu"), "muh")
     236          self.assertEqual(value.get("cat"), "meeow")
     237          self.assertEqual(value.get("dog"), "grrr")
     238          self.assertEqual(value.get("bird"), "tchilp")
     239
     240 -    def test_data_element_data_element_arg(self):
     241          # Check that DataElement preserves all attributes ObjectifiedDataElement
     242          # arguments
     243          arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
     244                                      attrib={"gnu": "muh", "cat": "meeow",
     245                                              "dog": "wuff"},
     246                                      bird="tchilp", dog="grrr")
     247          value = objectify.DataElement(arg)
     248          self.assertTrue(isinstance(value, objectify.StringElement))
     249          for attr in arg.attrib:
     250              self.assertEqual(value.get(attr), arg.get(attr))
     251
     252 -    def test_data_element_data_element_arg_pytype_none(self):
     253          # Check that _pytype arg overrides original py:pytype of
     254          # ObjectifiedDataElement
     255          arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
     256                                      attrib={"gnu": "muh", "cat": "meeow",
     257                                              "dog": "wuff"},
     258                                      bird="tchilp", dog="grrr")
     259          value = objectify.DataElement(arg, _pytype="NoneType")
     260          self.assertTrue(isinstance(value, objectify.NoneElement))
     261          self.assertEqual(value.get(XML_SCHEMA_NIL_ATTR), "true")
     262          self.assertEqual(value.text, None)
     263          self.assertEqual(value.pyval, None)
     264          for attr in arg.attrib:
     265              #if not attr == objectify.PYTYPE_ATTRIBUTE:
     266              self.assertEqual(value.get(attr), arg.get(attr))
     267
     268 -    def test_data_element_data_element_arg_pytype(self):
     269          # Check that _pytype arg overrides original py:pytype of
     270          # ObjectifiedDataElement
     271          arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
     272                                      attrib={"gnu": "muh", "cat": "meeow",
     273                                              "dog": "wuff"},
     274                                      bird="tchilp", dog="grrr")
     275          value = objectify.DataElement(arg, _pytype="int")
     276          self.assertTrue(isinstance(value, objectify.IntElement))
     277          self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
     278          for attr in arg.attrib:
     279              if not attr == objectify.PYTYPE_ATTRIBUTE:
     280                  self.assertEqual(value.get(attr), arg.get(attr))
     281
     282 -    def test_data_element_data_element_arg_xsitype(self):
     283          # Check that _xsi arg overrides original xsi:type of given
     284          # ObjectifiedDataElement
     285          arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
     286                                      attrib={"gnu": "muh", "cat": "meeow",
     287                                              "dog": "wuff"},
     288                                      bird="tchilp", dog="grrr")
     289          value = objectify.DataElement(arg, _xsi="xsd:int")
     290          self.assertTrue(isinstance(value, objectify.IntElement))
     291          self.assertEqual(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
     292          self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
     293          for attr in arg.attrib:
     294              if not attr in [objectify.PYTYPE_ATTRIBUTE,
     295                              XML_SCHEMA_INSTANCE_TYPE_ATTR]:
     296                  self.assertEqual(value.get(attr), arg.get(attr))
     297
     298 -    def test_data_element_data_element_arg_pytype_xsitype(self):
     299          # Check that _pytype and _xsi args override original py:pytype and
     300          # xsi:type attributes of given ObjectifiedDataElement
     301          arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
     302                                      attrib={"gnu": "muh", "cat": "meeow",
     303                                              "dog": "wuff"},
     304                                      bird="tchilp", dog="grrr")
     305          value = objectify.DataElement(arg, _pytype="int", _xsi="xsd:int")
     306          self.assertTrue(isinstance(value, objectify.IntElement))
     307          self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
     308          self.assertEqual(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
     309          for attr in arg.attrib:
     310              if not attr in [objectify.PYTYPE_ATTRIBUTE,
     311                              XML_SCHEMA_INSTANCE_TYPE_ATTR]:
     312                  self.assertEqual(value.get(attr), arg.get(attr))
     313
     314 -    def test_data_element_invalid_pytype(self):
     315          self.assertRaises(ValueError, objectify.DataElement, 3.1415,
     316                            _pytype="int")
     317
     318 -    def test_data_element_invalid_xsi(self):
     319          self.assertRaises(ValueError, objectify.DataElement, 3.1415,
     320                            _xsi="xsd:int")
     321
     322 -    def test_data_element_data_element_arg_invalid_pytype(self):
     323          arg = objectify.DataElement(3.1415)
     324          self.assertRaises(ValueError, objectify.DataElement, arg,
     325                            _pytype="int")
     326
     327 -    def test_data_element_data_element_arg_invalid_xsi(self):
     328          arg = objectify.DataElement(3.1415)
     329          self.assertRaises(ValueError, objectify.DataElement, arg,
     330                            _xsi="xsd:int")
     331
     332 -    def test_data_element_element_arg(self):
     333          arg = objectify.Element('arg')
     334          value = objectify.DataElement(arg)
     335          self.assertTrue(isinstance(value, objectify.ObjectifiedElement))
     336          for attr in arg.attrib:
     337              self.assertEqual(value.get(attr), arg.get(attr))
     338
     339 -    def test_root(self):
     340          root = self.Element("test")
     341          self.assertTrue(isinstance(root, objectify.ObjectifiedElement))
     342
     343 -    def test_str(self):
     344          root = self.Element("test")
     345          self.assertEqual('', str(root))
     346
     347 -    def test_child(self):
     348          root = self.XML(xml_str)
     349          self.assertEqual("0", root.c1.c2.text)
     350
     351 -    def test_child_ns_nons(self):
     352          root = self.XML("""
     353              <root>
     354                  <foo:x xmlns:foo="/foo/bar">1</foo:x>
     355                  <x>2</x>
     356              </root>
     357          """)
     358          self.assertEqual(2, root.x)
     359
     360 -    def test_countchildren(self):
     361          root = self.XML(xml_str)
     362          self.assertEqual(1, root.countchildren())
     363          self.assertEqual(5, root.c1.countchildren())
     364
     365 -    def test_child_getattr(self):
     366          root = self.XML(xml_str)
     367          self.assertEqual("0", getattr(root.c1, "{objectified}c2").text)
     368          self.assertEqual("3", getattr(root.c1, "{otherNS}c2").text)
     369
     370 -    def test_child_nonexistant(self):
     371          root = self.XML(xml_str)
     372          self.assertRaises(AttributeError, getattr, root.c1, "NOT_THERE")
     373          self.assertRaises(AttributeError, getattr, root.c1, "{unknownNS}c2")
     374
     375 -    def test_child_getattr_empty_ns(self):
     376          root = self.XML(xml_str)
     377          self.assertEqual("4", getattr(root.c1, "{}c2").text)
     378          self.assertEqual("0", getattr(root.c1, "c2").text)
     379
     380 -    def test_setattr(self):
     381          for val in [
     382              2, 2**32, 1.2, "Won't get fooled again",
     383              _str("W\xf6n't get f\xf6\xf6led \xe4g\xe4in", 'ISO-8859-1'), True,
     384              False, None]:
     385              root = self.Element('root')
     386              attrname = 'val'
     387              setattr(root, attrname, val)
     388              result = getattr(root, attrname)
     389              self.assertEqual(val, result)
     390              self.assertEqual(type(val), type(result.pyval))
     391
     392 -    def test_setattr_nonunicode(self):
     393          root = self.Element('root')
     394          attrname = 'val'
     395          val = _bytes("W\xf6n't get f\xf6\xf6led \xe4g\xe4in", 'ISO-8859-1')
     396          self.assertRaises(ValueError, setattr, root, attrname, val)
     397          self.assertRaises(AttributeError, getattr, root, attrname)
     398
     399 -    def test_addattr(self):
     400          root = self.XML(xml_str)
     401          self.assertEqual(1, len(root.c1))
     402          root.addattr("c1", "test")
     403          self.assertEqual(2, len(root.c1))
     404          self.assertEqual("test", root.c1[1].text)
     405
     406 -    def test_addattr_element(self):
     407          root = self.XML(xml_str)
     408          self.assertEqual(1, len(root.c1))
     409
     410          new_el = self.Element("test", myattr="5")
     411          root.addattr("c1", new_el)
     412          self.assertEqual(2, len(root.c1))
     413          self.assertEqual(None, root.c1[0].get("myattr"))
     414          self.assertEqual("5",  root.c1[1].get("myattr"))
     415
     416 -    def test_addattr_list(self):
     417          root = self.XML(xml_str)
     418          self.assertEqual(1, len(root.c1))
     419
     420          new_el = self.Element("test")
     421          self.etree.SubElement(new_el, "a", myattr="A")
     422          self.etree.SubElement(new_el, "a", myattr="B")
     423
     424          root.addattr("c1", list(new_el.a))
     425          self.assertEqual(3, len(root.c1))
     426          self.assertEqual(None, root.c1[0].get("myattr"))
     427          self.assertEqual("A",  root.c1[1].get("myattr"))
     428          self.assertEqual("B",  root.c1[2].get("myattr"))
     429
     430 -    def test_child_addattr(self):
     431          root = self.XML(xml_str)
     432          self.assertEqual(3, len(root.c1.c2))
     433          root.c1.addattr("c2", 3)
     434          self.assertEqual(4, len(root.c1.c2))
     435          self.assertEqual("3", root.c1.c2[3].text)
     436
     437 -    def test_child_index(self):
     438          root = self.XML(xml_str)
     439          self.assertEqual("0", root.c1.c2[0].text)
     440          self.assertEqual("1", root.c1.c2[1].text)
     441          self.assertEqual("2", root.c1.c2[2].text)
     442          self.assertRaises(IndexError, operator.getitem, root.c1.c2, 3)
     443
     444 -    def test_child_index_neg(self):
     445          root = self.XML(xml_str)
     446          self.assertEqual("0", root.c1.c2[0].text)
     447          self.assertEqual("0", root.c1.c2[-3].text)
     448          self.assertEqual("1", root.c1.c2[-2].text)
     449          self.assertEqual("2", root.c1.c2[-1].text)
     450          self.assertRaises(IndexError, operator.getitem, root.c1.c2, -4)
     451
     452 -    def test_child_len(self):
     453          root = self.XML(xml_str)
     454          self.assertEqual(1, len(root))
     455          self.assertEqual(1, len(root.c1))
     456          self.assertEqual(3, len(root.c1.c2))
     457
     458 -    def test_child_iter(self):
     459          root = self.XML(xml_str)
     460          self.assertEqual([root],
     461                            list(iter(root)))
     462          self.assertEqual([root.c1],
     463                            list(iter(root.c1)))
     464          self.assertEqual([root.c1.c2[0], root.c1.c2[1], root.c1.c2[2]],
     465                            list(iter((root.c1.c2))))
     466
     467 -    def test_class_lookup(self):
     468          root = self.XML(xml_str)
     469          self.assertTrue(isinstance(root.c1.c2, objectify.ObjectifiedElement))
     470          self.assertFalse(isinstance(getattr(root.c1, "{otherNS}c2"),
     471                                      objectify.ObjectifiedElement))
     472
     473 -    def test_dir(self):
     474          root = self.XML(xml_str)
     475          dir_c1 = dir(objectify.ObjectifiedElement) + ['c1']
     476          dir_c1.sort()
     477          dir_c2 = dir(objectify.ObjectifiedElement) + ['c2']
     478          dir_c2.sort()
     479
     480          self.assertEqual(dir_c1, dir(root))
     481          self.assertEqual(dir_c2, dir(root.c1))
     482
     483 -    def test_vars(self):
     484          root = self.XML(xml_str)
     485          self.assertEqual({'c1' : root.c1},    vars(root))
     486          self.assertEqual({'c2' : root.c1.c2}, vars(root.c1))
     487
     488 -    def test_child_set_ro(self):
     489          root = self.XML(xml_str)
     490          self.assertRaises(TypeError, setattr, root.c1.c2, 'text',  "test")
     491          self.assertRaises(TypeError, setattr, root.c1.c2, 'pyval', "test")
     492
     493      # slicing
     494
     495 -    def test_getslice_complete(self):
     496          root = self.XML("<root><c>c1</c><c>c2</c></root>")
     497          self.assertEqual(["c1", "c2"],
     498                            [ c.text for c in root.c[:] ])
     499
     500 -    def test_getslice_partial(self):
     501          root = self.XML("<root><c>c1</c><c>c2</c><c>c3</c><c>c4</c></root>")
     502          test_list = ["c1", "c2", "c3", "c4"]
     503
     504          self.assertEqual(test_list,
     505                            [ c.text for c in root.c[:] ])
     506          self.assertEqual(test_list[1:2],
     507                            [ c.text for c in root.c[1:2] ])
     508          self.assertEqual(test_list[-3:-1],
     509                            [ c.text for c in root.c[-3:-1] ])
     510          self.assertEqual(test_list[-3:3],
     511                            [ c.text for c in root.c[-3:3] ])
     512          self.assertEqual(test_list[-3000:3],
     513                            [ c.text for c in root.c[-3000:3] ])
     514          self.assertEqual(test_list[-3:3000],
     515                            [ c.text for c in root.c[-3:3000] ])
     516
     517 -    def test_getslice_partial_neg(self):
     518          root = self.XML("<root><c>c1</c><c>c2</c><c>c3</c><c>c4</c></root>")
     519          test_list = ["c1", "c2", "c3", "c4"]
     520
     521          self.assertEqual(test_list,
     522                            [ c.text for c in root.c[:] ])
     523          self.assertEqual(test_list[2:1:-1],
     524                            [ c.text for c in root.c[2:1:-1] ])
     525          self.assertEqual(test_list[-1:-3:-1],
     526                            [ c.text for c in root.c[-1:-3:-1] ])
     527          self.assertEqual(test_list[2:-3:-1],
     528                            [ c.text for c in root.c[2:-3:-1] ])
     529          self.assertEqual(test_list[2:-3000:-1],
     530                            [ c.text for c in root.c[2:-3000:-1] ])
     531
     532      # slice assignment
     533
     534 -    def test_setslice_complete(self):
     535          Element = self.Element
     536          root = Element("root")
     537          root.c = ["c1", "c2"]
     538
     539          c1 = root.c[0]
     540          c2 = root.c[1]
     541
     542          self.assertEqual([c1,c2], list(root.c))
     543          self.assertEqual(["c1", "c2"],
     544                            [ c.text for c in root.c ])
     545
     546 -    def test_setslice_elements(self):
     547          Element = self.Element
     548          root = Element("root")
     549          root.c = ["c1", "c2"]
     550
     551          c1 = root.c[0]
     552          c2 = root.c[1]
     553
     554          self.assertEqual([c1,c2], list(root.c))
     555          self.assertEqual(["c1", "c2"],
     556                            [ c.text for c in root.c ])
     557
     558          root2 = Element("root2")
     559          root2.el = [ "test", "test" ]
     560          self.assertEqual(["test", "test"],
     561                            [ el.text for el in root2.el ])
     562
     563          root.c = [ root2.el, root2.el ]
     564          self.assertEqual(["test", "test"],
     565                            [ c.text for c in root.c ])
     566          self.assertEqual(["test", "test"],
     567                            [ el.text for el in root2.el ])
     568
     569          root.c[:] = [ c1, c2, c2, c1 ]
     570          self.assertEqual(["c1", "c2", "c2", "c1"],
     571                            [ c.text for c in root.c ])
     572
     573 -    def test_setslice_partial(self):
     574          Element = self.Element
     575          root = Element("root")
     576          l = ["c1", "c2", "c3", "c4"]
     577          root.c = l
     578
     579          self.assertEqual(["c1", "c2", "c3", "c4"],
     580                            [ c.text for c in root.c ])
     581          self.assertEqual(l,
     582                            [ c.text for c in root.c ])
     583
     584          new_slice = ["cA", "cB"]
     585          l[1:2] = new_slice
     586          root.c[1:2] = new_slice
     587
     588          self.assertEqual(["c1", "cA", "cB", "c3", "c4"], l)
     589          self.assertEqual(["c1", "cA", "cB", "c3", "c4"],
     590                            [ c.text for c in root.c ])
     591          self.assertEqual(l,
     592                            [ c.text for c in root.c ])
     593
     594 -    def test_setslice_insert(self):
     595          Element = self.Element
     596          root = Element("root")
     597          l = ["c1", "c2", "c3", "c4"]
     598          root.c = l
     599
     600          self.assertEqual(["c1", "c2", "c3", "c4"],
     601                            [ c.text for c in root.c ])
     602          self.assertEqual(l,
     603                            [ c.text for c in root.c ])
     604
     605          new_slice = ["cA", "cB"]
     606          l[1:1] = new_slice
     607          root.c[1:1] = new_slice
     608
     609          self.assertEqual(["c1", "cA", "cB", "c2", "c3", "c4"], l)
     610          self.assertEqual(["c1", "cA", "cB", "c2", "c3", "c4"],
     611                            [ c.text for c in root.c ])
     612          self.assertEqual(l,
     613                            [ c.text for c in root.c ])
     614
     615 -    def test_setslice_insert_neg(self):
     616          Element = self.Element
     617          root = Element("root")
     618          l = ["c1", "c2", "c3", "c4"]
     619          root.c = l
     620
     621          self.assertEqual(["c1", "c2", "c3", "c4"],
     622                            [ c.text for c in root.c ])
     623          self.assertEqual(l,
     624                            [ c.text for c in root.c ])
     625
     626          new_slice = ["cA", "cB"]
     627          l[-2:-2] = new_slice
     628          root.c[-2:-2] = new_slice
     629
     630          self.assertEqual(["c1", "c2", "cA", "cB", "c3", "c4"], l)
     631          self.assertEqual(["c1", "c2", "cA", "cB", "c3", "c4"],
     632                            [ c.text for c in root.c ])
     633          self.assertEqual(l,
     634                            [ c.text for c in root.c ])
     635
     636 -    def test_setslice_empty(self):
     637          Element = self.Element
     638          root = Element("root")
     639
     640          root.c = []
     641          self.assertRaises(
     642              AttributeError, getattr, root, 'c')
     643
     644 -    def test_setslice_partial_wrong_length(self):
     645          Element = self.Element
     646          root = Element("root")
     647          l = ["c1", "c2", "c3", "c4"]
     648          root.c = l
     649
     650          self.assertEqual(["c1", "c2", "c3", "c4"],
     651                            [ c.text for c in root.c ])
     652          self.assertEqual(l,
     653                            [ c.text for c in root.c ])
     654
     655          new_slice = ["cA", "cB", "cC"]
     656          self.assertRaises(
     657              ValueError, operator.setitem,
     658              l, slice(1,2,-1), new_slice)
     659          self.assertRaises(
     660              ValueError, operator.setitem,
     661              root.c, slice(1,2,-1), new_slice)
     662
     663 -    def test_setslice_partial_neg(self):
     664          Element = self.Element
     665          root = Element("root")
     666          l = ["c1", "c2", "c3", "c4"]
     667          root.c = l
     668
     669          self.assertEqual(["c1", "c2", "c3", "c4"],
     670                            [ c.text for c in root.c ])
     671          self.assertEqual(l,
     672                            [ c.text for c in root.c ])
     673
     674          new_slice = ["cA", "cB"]
     675          l[-1:1:-1] = new_slice
     676          root.c[-1:1:-1] = new_slice
     677
     678          self.assertEqual(["c1", "c2", "cB", "cA"], l)
     679          self.assertEqual(["c1", "c2", "cB", "cA"],
     680                            [ c.text for c in root.c ])
     681          self.assertEqual(l,
     682                            [ c.text for c in root.c ])
     683
     684 -    def test_setslice_partial_allneg(self):
     685          Element = self.Element
     686          root = Element("root")
     687          l = ["c1", "c2", "c3", "c4"]
     688          root.c = l
     689
     690          self.assertEqual(["c1", "c2", "c3", "c4"],
     691                            [ c.text for c in root.c ])
     692          self.assertEqual(l,
     693                            [ c.text for c in root.c ])
     694
     695          new_slice = ["cA", "cB"]
     696          l[-1:-4:-2] = new_slice
     697          root.c[-1:-4:-2] = new_slice
     698
     699          self.assertEqual(["c1", "cB", "c3", "cA"], l)
     700          self.assertEqual(["c1", "cB", "c3", "cA"],
     701                            [ c.text for c in root.c ])
     702          self.assertEqual(l,
     703                            [ c.text for c in root.c ])
     704
     705      # other stuff
     706
     707 -    def test_set_string(self):
     708          # make sure strings are not handled as sequences
     709          Element = self.Element
     710          root = Element("root")
     711          root.c = "TEST"
     712          self.assertEqual(["TEST"],
     713                            [ c.text for c in root.c ])
     714
     715 -    def test_setitem_string(self):
     716          # make sure strings are set as children
     717          Element = self.Element
     718          root = Element("root")
     719          root["c"] = "TEST"
     720          self.assertEqual(["TEST"],
     721                            [ c.text for c in root.c ])
     722
     723 -    def test_setitem_string_special(self):
     724          # make sure 'text' etc. are set as children
     725          Element = self.Element
     726          root = Element("root")
     727
     728          root["text"] = "TEST"
     729          self.assertEqual(["TEST"],
     730                            [ c.text for c in root["text"] ])
     731
     732          root["tail"] = "TEST"
     733          self.assertEqual(["TEST"],
     734                            [ c.text for c in root["tail"] ])
     735
     736          root["pyval"] = "TEST"
     737          self.assertEqual(["TEST"],
     738                            [ c.text for c in root["pyval"] ])
     739
     740          root["tag"] = "TEST"
     741          self.assertEqual(["TEST"],
     742                            [ c.text for c in root["tag"] ])
     743
     744 -    def test_findall(self):
     745          XML = self.XML
     746          root = XML('<a><b><c/></b><b/><c><b/></c></a>')
     747          self.assertEqual(1, len(root.findall("c")))
     748          self.assertEqual(2, len(root.findall(".//c")))
     749          self.assertEqual(3, len(root.findall(".//b")))
     750          self.assertTrue(root.findall(".//b")[1] is root.getchildren()[1])
     751
     752 -    def test_findall_ns(self):
     753          XML = self.XML
     754          root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')
     755          self.assertEqual(2, len(root.findall(".//{X}b")))
     756          self.assertEqual(3, len(root.findall(".//b")))
     757          self.assertEqual(2, len(root.findall("b")))
     758
     759 -    def test_build_tree(self):
     760          root = self.Element('root')
     761          root.a = 5
     762          root.b = 6
     763          self.assertTrue(isinstance(root, objectify.ObjectifiedElement))
     764          self.assertTrue(isinstance(root.a, objectify.IntElement))
     765          self.assertTrue(isinstance(root.b, objectify.IntElement))
     766
     767 -    def test_type_NoneType(self):
     768          Element = self.Element
     769          SubElement = self.etree.SubElement
     770
     771          nil_attr = XML_SCHEMA_NIL_ATTR
     772          root = Element("{objectified}root")
     773          SubElement(root, "{objectified}none")
     774          SubElement(root, "{objectified}none", {nil_attr : "true"})
     775          self.assertFalse(isinstance(root.none, objectify.NoneElement))
     776          self.assertFalse(isinstance(root.none[0], objectify.NoneElement))
     777          self.assertTrue(isinstance(root.none[1], objectify.NoneElement))
     778          self.assertEqual(hash(root.none[1]), hash(None))
     779          self.assertEqual(root.none[1], None)
     780          self.assertFalse(root.none[1])
     781
     782 -    def test_data_element_NoneType(self):
     783          value = objectify.DataElement(None)
     784          self.assertTrue(isinstance(value, objectify.NoneElement))
     785          self.assertEqual(value, None)
     786          self.assertEqual(value.get(XML_SCHEMA_NIL_ATTR), "true")
     787
     788 -    def test_type_bool(self):
     789          Element = self.Element
     790          SubElement = self.etree.SubElement
     791          root = Element("{objectified}root")
     792          root.bool = True
     793          self.assertEqual(root.bool, True)
     794          self.assertEqual(root.bool + root.bool, True + True)
     795          self.assertEqual(True + root.bool, True + root.bool)
     796          self.assertEqual(root.bool * root.bool, True * True)
     797          self.assertEqual(int(root.bool), int(True))
     798          self.assertEqual(hash(root.bool), hash(True))
     799          self.assertEqual(complex(root.bool), complex(True))
     800          self.assertTrue(isinstance(root.bool, objectify.BoolElement))
     801
     802          root.bool = False
     803          self.assertEqual(root.bool, False)
     804          self.assertEqual(root.bool + root.bool, False + False)
     805          self.assertEqual(False + root.bool, False + root.bool)
     806          self.assertEqual(root.bool * root.bool, False * False)
     807          self.assertEqual(int(root.bool), int(False))
     808          self.assertEqual(hash(root.bool), hash(False))
     809          self.assertEqual(complex(root.bool), complex(False))
     810          self.assertTrue(isinstance(root.bool, objectify.BoolElement))
     811
     812 -    def test_data_element_bool(self):
     813          value = objectify.DataElement(True)
     814          self.assertTrue(isinstance(value, objectify.BoolElement))
     815          self.assertEqual(value, True)
     816
     817          value = objectify.DataElement(False)
     818          self.assertTrue(isinstance(value, objectify.BoolElement))
     819          self.assertEqual(value, False)
     820
     821 -    def test_type_str(self):
     822          Element = self.Element
     823          SubElement = self.etree.SubElement
     824          root = Element("{objectified}root")
     825          root.s = "test"
     826          self.assertTrue(isinstance(root.s, objectify.StringElement))
     827
     828 -    def test_type_str_intliteral(self):
     829          Element = self.Element
     830          SubElement = self.etree.SubElement
     831          root = Element("{objectified}root")
     832          root.s = "3"
     833          self.assertTrue(isinstance(root.s, objectify.StringElement))
     834
     835 -    def test_type_str_floatliteral(self):
     836          Element = self.Element
     837          SubElement = self.etree.SubElement
     838          root = Element("{objectified}root")
     839          root.s = "3.72"
     840          self.assertTrue(isinstance(root.s, objectify.StringElement))
     841
     842 -    def test_type_str_mul(self):
     843          Element = self.Element
     844          SubElement = self.etree.SubElement
     845          root = Element("{objectified}root")
     846          root.s = "test"
     847
     848          self.assertEqual("test" * 5, root.s * 5)
     849          self.assertEqual(5 * "test", 5 * root.s)
     850
     851          self.assertRaises(TypeError, operator.mul, root.s, "honk")
     852          self.assertRaises(TypeError, operator.mul, "honk", root.s)
     853
     854 -    def test_type_str_add(self):
     855          Element = self.Element
     856          SubElement = self.etree.SubElement
     857          root = Element("{objectified}root")
     858          root.s = "test"
     859
     860          s = "toast"
     861          self.assertEqual("test" + s, root.s + s)
     862          self.assertEqual(s + "test", s + root.s)
     863
     864 -    def test_type_str_mod(self):
     865          s = "%d %f %s %r"
     866          el = objectify.DataElement(s)
     867          values = (1, 7.0, "abcd", None)
     868          self.assertEqual(s % values, el % values)
     869
     870          s = "%d"
     871          el = objectify.DataElement(s)
     872          val = 5
     873          self.assertEqual(s % val, el % val)
     874
     875          s = "%d %s"
     876          el = objectify.DataElement(s)
     877          val = 5
     878          self.assertRaises(TypeError, el.__mod__, val)
     879
     880          s = ""
     881          el = objectify.DataElement(s)
     882          val = 5
     883          self.assertRaises(TypeError, el.__mod__, val)
     884
     885 -    def test_type_str_hash(self):
     886          v = "1"
     887          el = objectify.DataElement(v)
     888          self.assertEqual(hash(el), hash("1"))
     889
     890 -    def test_type_str_as_int(self):
     891          v = "1"
     892          el = objectify.DataElement(v)
     893          self.assertEqual(int(el), 1)
     894
     895 -    def test_type_str_as_float(self):
     896          v = "1"
     897          el = objectify.DataElement(v)
     898          self.assertEqual(float(el), 1)
     899
     900 -    def test_type_str_as_complex(self):
     901          v = "1"
     902          el = objectify.DataElement(v)
     903          self.assertEqual(complex(el), 1)
     904
     905 -    def test_type_str_mod_data_elements(self):
     906          s = "%d %f %s %r"
     907          el = objectify.DataElement(s)
     908          values = (objectify.DataElement(1),
     909                    objectify.DataElement(7.0),
     910                    objectify.DataElement("abcd"),
     911                    objectify.DataElement(None))
     912          self.assertEqual(s % values, el % values)
     913
     914 -    def test_data_element_str(self):
     915          value = objectify.DataElement("test")
     916          self.assertTrue(isinstance(value, objectify.StringElement))
     917          self.assertEqual(value, "test")
     918
     919 -    def test_data_element_str_intliteral(self):
     920          value = objectify.DataElement("3")
     921          self.assertTrue(isinstance(value, objectify.StringElement))
     922          self.assertEqual(value, "3")
     923
     924 -    def test_data_element_str_floatliteral(self):
     925          value = objectify.DataElement("3.20")
     926          self.assertTrue(isinstance(value, objectify.StringElement))
     927          self.assertEqual(value, "3.20")
     928
     929 -    def test_type_ustr(self):
     930          Element = self.Element
     931          SubElement = self.etree.SubElement
     932          root = Element("{objectified}root")
     933          root.s = _str("test")
     934          self.assertTrue(isinstance(root.s, objectify.StringElement))
     935
     936 -    def test_type_ustr_intliteral(self):
     937          Element = self.Element
     938          SubElement = self.etree.SubElement
     939          root = Element("{objectified}root")
     940          root.s = _str("3")
     941          self.assertTrue(isinstance(root.s, objectify.StringElement))
     942
     943 -    def test_type_ustr_floatliteral(self):
     944          Element = self.Element
     945          SubElement = self.etree.SubElement
     946          root = Element("{objectified}root")
     947          root.s = _str("3.72")
     948          self.assertTrue(isinstance(root.s, objectify.StringElement))
     949
     950 -    def test_type_ustr_mul(self):
     951          Element = self.Element
     952          SubElement = self.etree.SubElement
     953          root = Element("{objectified}root")
     954          root.s = _str("test")
     955
     956          self.assertEqual(_str("test") * 5, root.s * 5)
     957          self.assertEqual(5 * _str("test"), 5 * root.s)
     958
     959          self.assertRaises(TypeError, operator.mul, root.s, _str("honk"))
     960          self.assertRaises(TypeError, operator.mul, _str("honk"), root.s)
     961
     962 -    def test_type_ustr_add(self):
     963          Element = self.Element
     964          SubElement = self.etree.SubElement
     965          root = Element("{objectified}root")
     966          root.s = _str("test")
     967
     968          s = _str("toast")
     969          self.assertEqual(_str("test") + s, root.s + s)
     970          self.assertEqual(s + _str("test"), s + root.s)
     971
     972 -    def test_data_element_ustr(self):
     973          value = objectify.DataElement(_str("test"))
     974          self.assertTrue(isinstance(value, objectify.StringElement))
     975          self.assertEqual(value, _str("test"))
     976
     977 -    def test_data_element_ustr_intliteral(self):
     978          value = objectify.DataElement("3")
     979          self.assertTrue(isinstance(value, objectify.StringElement))
     980          self.assertEqual(value, _str("3"))
     981
     982 -    def test_data_element_ustr_floatliteral(self):
     983          value = objectify.DataElement(_str("3.20"))
     984          self.assertTrue(isinstance(value, objectify.StringElement))
     985          self.assertEqual(value, _str("3.20"))
     986
     987 -    def test_type_int(self):
     988          Element = self.Element
     989          SubElement = self.etree.SubElement
     990          root = Element("{objectified}root")
     991          root.none = 5
     992          self.assertTrue(isinstance(root.none, objectify.IntElement))
     993
     994 -    def test_data_element_int(self):
     995          value = objectify.DataElement(5)
     996          self.assertTrue(isinstance(value, objectify.IntElement))
     997          self.assertEqual(value, 5)
     998
     999 -    def test_data_element_int_hash(self):
    1000          value = objectify.DataElement(123)
    1001          self.assertEqual(hash(value), hash(123))
    1002
    1003 -    def test_type_float(self):
    1004          Element = self.Element
    1005          SubElement = self.etree.SubElement
    1006          root = Element("{objectified}root")
    1007          root.none = 5.5
    1008          self.assertTrue(isinstance(root.none, objectify.FloatElement))
    1009
    1010 -    def test_data_element_float(self):
    1011          value = objectify.DataElement(5.5)
    1012          self.assertTrue(isinstance(value, objectify.FloatElement))
    1013          self.assertEqual(value, 5.5)
    1014
    1015 -    def test_data_element_float_hash(self):
    1016          value = objectify.DataElement(5.5)
    1017          self.assertEqual(hash(value), hash(5.5))
    1018
    1019 -    def test_data_element_xsitypes(self):
    1020          for xsi, objclass in xsitype2objclass.items():
    1021              # 1 is a valid value for all ObjectifiedDataElement classes
    1022              pyval = 1
    1023              value = objectify.DataElement(pyval, _xsi=xsi)
    1024              self.assertTrue(isinstance(value, objclass),
    1025                           "DataElement(%s, _xsi='%s') returns %s, expected %s"
    1026                           % (pyval, xsi, type(value), objclass))
    1027
    1028 -    def test_data_element_xsitypes_xsdprefixed(self):
    1029          for xsi, objclass in xsitype2objclass.items():
    1030              # 1 is a valid value for all ObjectifiedDataElement classes
    1031              pyval = 1
    1032              value = objectify.DataElement(pyval, _xsi="xsd:%s" % xsi)
    1033              self.assertTrue(isinstance(value, objclass),
    1034                           "DataElement(%s, _xsi='%s') returns %s, expected %s"
    1035                           % (pyval, xsi, type(value), objclass))
    1036
    1037 -    def test_data_element_xsitypes_prefixed(self):
    1038          for xsi, objclass in xsitype2objclass.items():
    1039              # 1 is a valid value for all ObjectifiedDataElement classes
    1040              self.assertRaises(ValueError, objectify.DataElement, 1,
    1041                                _xsi="foo:%s" % xsi)
    1042
    1043 -    def test_data_element_pytypes(self):
    1044          for pytype, objclass in pytype2objclass.items():
    1045              # 1 is a valid value for all ObjectifiedDataElement classes
    1046              pyval = 1
    1047              value = objectify.DataElement(pyval, _pytype=pytype)
    1048              self.assertTrue(isinstance(value, objclass),
    1049                           "DataElement(%s, _pytype='%s') returns %s, expected %s"
    1050                           % (pyval, pytype, type(value), objclass))
    1051
    1052 -    def test_data_element_pytype_none(self):
    1053          pyval = 1
    1054          pytype = "NoneType"
    1055          objclass = objectify.NoneElement
    1056          value = objectify.DataElement(pyval, _pytype=pytype)
    1057          self.assertTrue(isinstance(value, objclass),
    1058                       "DataElement(%s, _pytype='%s') returns %s, expected %s"
    1059                       % (pyval, pytype, type(value), objclass))
    1060          self.assertEqual(value.text, None)
    1061          self.assertEqual(value.pyval, None)
    1062
    1063 -    def test_data_element_pytype_none_compat(self):
    1064          # pre-2.0 lxml called NoneElement "none"
    1065          pyval = 1
    1066          pytype = "none"
    1067          objclass = objectify.NoneElement
    1068          value = objectify.DataElement(pyval, _pytype=pytype)
    1069          self.assertTrue(isinstance(value, objclass),
    1070                       "DataElement(%s, _pytype='%s') returns %s, expected %s"
    1071                       % (pyval, pytype, type(value), objclass))
    1072          self.assertEqual(value.text, None)
    1073          self.assertEqual(value.pyval, None)
    1074
    1075 -    def test_type_unregistered(self):
    1076          Element = self.Element
    1077          SubElement = self.etree.SubElement
    1078          class MyFloat(float):
    1079              pass
    1080          root = Element("{objectified}root")
    1081          root.myfloat = MyFloat(5.5)
    1082          self.assertTrue(isinstance(root.myfloat, objectify.FloatElement))
    1083          self.assertEqual(root.myfloat.get(objectify.PYTYPE_ATTRIBUTE), None)
    1084
    1085 -    def test_data_element_unregistered(self):
    1086          class MyFloat(float):
    1087              pass
    1088          value = objectify.DataElement(MyFloat(5.5))
    1089          self.assertTrue(isinstance(value, objectify.FloatElement))
    1090          self.assertEqual(value, 5.5)
    1091          self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), None)
    1092
    1093 -    def test_schema_types(self):
    1094          XML = self.XML
    1095          root = XML('''\
    1096          <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    1097            <b xsi:type="boolean">true</b>
    1098            <b xsi:type="boolean">false</b>
    1099            <b xsi:type="boolean">1</b>
    1100            <b xsi:type="boolean">0</b>
    1101
    1102            <f xsi:type="float">5</f>
    1103            <f xsi:type="double">5</f>
    1104
    1105            <s xsi:type="string">5</s>
    1106            <s xsi:type="normalizedString">5</s>
    1107            <s xsi:type="token">5</s>
    1108            <s xsi:type="language">5</s>
    1109            <s xsi:type="Name">5</s>
    1110            <s xsi:type="NCName">5</s>
    1111            <s xsi:type="ID">5</s>
    1112            <s xsi:type="IDREF">5</s>
    1113            <s xsi:type="ENTITY">5</s>
    1114            <s xsi:type="NMTOKEN">5</s>
    1115
    1116            <l xsi:type="integer">5</l>
    1117            <l xsi:type="nonPositiveInteger">5</l>
    1118            <l xsi:type="negativeInteger">5</l>
    1119            <l xsi:type="long">5</l>
    1120            <l xsi:type="nonNegativeInteger">5</l>
    1121            <l xsi:type="unsignedLong">5</l>
    1122            <l xsi:type="unsignedInt">5</l>
    1123            <l xsi:type="positiveInteger">5</l>
    1124
    1125            <i xsi:type="int">5</i>
    1126            <i xsi:type="short">5</i>
    1127            <i xsi:type="byte">5</i>
    1128            <i xsi:type="unsignedShort">5</i>
    1129            <i xsi:type="unsignedByte">5</i>
    1130
    1131            <n xsi:nil="true"/>
    1132          </root>
    1133          ''')
    1134
    1135          for b in root.b:
    1136              self.assertTrue(isinstance(b, objectify.BoolElement))
    1137          self.assertEqual(True,  root.b[0])
    1138          self.assertEqual(False, root.b[1])
    1139          self.assertEqual(True,  root.b[2])
    1140          self.assertEqual(False, root.b[3])
    1141
    1142          for f in root.f:
    1143              self.assertTrue(isinstance(f, objectify.FloatElement))
    1144              self.assertEqual(5, f)
    1145
    1146          for s in root.s:
    1147              self.assertTrue(isinstance(s, objectify.StringElement))
    1148              self.assertEqual("5", s)
    1149
    1150          for i in root.i:
    1151              self.assertTrue(isinstance(i, objectify.IntElement))
    1152              self.assertEqual(5, i)
    1153
    1154          for l in root.l:
    1155              self.assertTrue(isinstance(l, objectify.IntElement))
    1156              self.assertEqual(5, i)
    1157
    1158          self.assertTrue(isinstance(root.n, objectify.NoneElement))
    1159          self.assertEqual(None, root.n)
    1160
    1161 -    def test_schema_types_prefixed(self):
    1162          XML = self.XML
    1163          root = XML('''\
    1164          <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1165          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    1166            <b xsi:type="xsd:boolean">true</b>
    1167            <b xsi:type="xsd:boolean">false</b>
    1168            <b xsi:type="xsd:boolean">1</b>
    1169            <b xsi:type="xsd:boolean">0</b>
    1170
    1171            <f xsi:type="xsd:float">5</f>
    1172            <f xsi:type="xsd:double">5</f>
    1173
    1174            <s xsi:type="xsd:string">5</s>
    1175            <s xsi:type="xsd:normalizedString">5</s>
    1176            <s xsi:type="xsd:token">5</s>
    1177            <s xsi:type="xsd:language">5</s>
    1178            <s xsi:type="xsd:Name">5</s>
    1179            <s xsi:type="xsd:NCName">5</s>
    1180            <s xsi:type="xsd:ID">5</s>
    1181            <s xsi:type="xsd:IDREF">5</s>
    1182            <s xsi:type="xsd:ENTITY">5</s>
    1183            <s xsi:type="xsd:NMTOKEN">5</s>
    1184
    1185            <l xsi:type="xsd:integer">5</l>
    1186            <l xsi:type="xsd:nonPositiveInteger">5</l>
    1187            <l xsi:type="xsd:negativeInteger">5</l>
    1188            <l xsi:type="xsd:long">5</l>
    1189            <l xsi:type="xsd:nonNegativeInteger">5</l>
    1190            <l xsi:type="xsd:unsignedLong">5</l>
    1191            <l xsi:type="xsd:unsignedInt">5</l>
    1192            <l xsi:type="xsd:positiveInteger">5</l>
    1193
    1194            <i xsi:type="xsd:int">5</i>
    1195            <i xsi:type="xsd:short">5</i>
    1196            <i xsi:type="xsd:byte">5</i>
    1197            <i xsi:type="xsd:unsignedShort">5</i>
    1198            <i xsi:type="xsd:unsignedByte">5</i>
    1199
    1200            <n xsi:nil="true"/>
    1201          </root>
    1202          ''')
    1203
    1204          for b in root.b:
    1205              self.assertTrue(isinstance(b, objectify.BoolElement))
    1206          self.assertEqual(True,  root.b[0])
    1207          self.assertEqual(False, root.b[1])
    1208          self.assertEqual(True,  root.b[2])
    1209          self.assertEqual(False, root.b[3])
    1210
    1211          for f in root.f:
    1212              self.assertTrue(isinstance(f, objectify.FloatElement))
    1213              self.assertEqual(5, f)
    1214
    1215          for s in root.s:
    1216              self.assertTrue(isinstance(s, objectify.StringElement))
    1217              self.assertEqual("5", s)
    1218
    1219          for i in root.i:
    1220              self.assertTrue(isinstance(i, objectify.IntElement))
    1221              self.assertEqual(5, i)
    1222
    1223          for l in root.l:
    1224              self.assertTrue(isinstance(l, objectify.IntElement))
    1225              self.assertEqual(5, l)
    1226
    1227          self.assertTrue(isinstance(root.n, objectify.NoneElement))
    1228          self.assertEqual(None, root.n)
    1229
    1230 -    def test_type_str_sequence(self):
    1231          XML = self.XML
    1232          root = XML(_bytes('<root><b>why</b><b>try</b></root>'))
    1233          strs = [ str(s) for s in root.b ]
    1234          self.assertEqual(["why", "try"],
    1235                            strs)
    1236
    1237 -    def test_type_str_cmp(self):
    1238          XML = self.XML
    1239          root = XML(_bytes('<root><b>test</b><b>taste</b><b></b><b/></root>'))
    1240          self.assertFalse(root.b[0] <  root.b[1])
    1241          self.assertFalse(root.b[0] <= root.b[1])
    1242          self.assertFalse(root.b[0] == root.b[1])
    1243
    1244          self.assertTrue(root.b[0] != root.b[1])
    1245          self.assertTrue(root.b[0] >= root.b[1])
    1246          self.assertTrue(root.b[0] >  root.b[1])
    1247
    1248          self.assertEqual(root.b[0], "test")
    1249          self.assertEqual("test", root.b[0])
    1250
    1251          self.assertEqual("", root.b[2])
    1252          self.assertEqual(root.b[2], "")
    1253          self.assertEqual("", root.b[3])
    1254          self.assertEqual(root.b[3], "")
    1255          self.assertEqual(root.b[2], root.b[3])
    1256
    1257          root.b = "test"
    1258          self.assertTrue(root.b)
    1259          root.b = ""
    1260          self.assertFalse(root.b)
    1261          self.assertEqual(root.b, "")
    1262          self.assertEqual("", root.b)
    1263
    1264 -    def test_type_int_cmp(self):
    1265          XML = self.XML
    1266          root = XML(_bytes('<root><b>5</b><b>6</b></root>'))
    1267          self.assertTrue(root.b[0] <  root.b[1])
    1268          self.assertTrue(root.b[0] <= root.b[1])
    1269          self.assertTrue(root.b[0] != root.b[1])
    1270
    1271          self.assertFalse(root.b[0] == root.b[1])
    1272          self.assertFalse(root.b[0] >= root.b[1])
    1273          self.assertFalse(root.b[0] >  root.b[1])
    1274
    1275          self.assertEqual(root.b[0], 5)
    1276          self.assertEqual(5, root.b[0])
    1277          self.assertNotEqual(root.b[0], "5")
    1278
    1279          root.b = 5
    1280          self.assertTrue(root.b)
    1281          root.b = 0
    1282          self.assertFalse(root.b)
    1283
    1284      # float + long share the NumberElement implementation with int
    1285
    1286 -    def test_type_bool_cmp(self):
    1287          XML = self.XML
    1288          root = XML(_bytes('<root><b>false</b><b>true</b></root>'))
    1289          self.assertTrue(root.b[0] <  root.b[1])
    1290          self.assertTrue(root.b[0] <= root.b[1])
    1291          self.assertTrue(root.b[0] != root.b[1])
    1292
    1293          self.assertFalse(root.b[0] == root.b[1])
    1294          self.assertFalse(root.b[0] >= root.b[1])
    1295          self.assertFalse(root.b[0] >  root.b[1])
    1296
    1297          self.assertFalse(root.b[0])
    1298          self.assertTrue(root.b[1])
    1299
    1300          self.assertEqual(root.b[0], False)
    1301          self.assertEqual(False, root.b[0])
    1302          self.assertTrue(root.b[0] <  5)
    1303          self.assertTrue(5 > root.b[0])
    1304
    1305          root.b = True
    1306          self.assertTrue(root.b)
    1307          root.b = False
    1308          self.assertFalse(root.b)
    1309
    1310 -    def test_type_none_cmp(self):
    1311          XML = self.XML
    1312          root = XML(_bytes("""
    1313          <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    1314            <b xsi:nil="true"></b><b xsi:nil="true"/>
    1315          </root>"""))
    1316          self.assertTrue(root.b[0] == root.b[1])
    1317          self.assertFalse(root.b[0])
    1318          self.assertEqual(root.b[0], None)
    1319          self.assertEqual(None, root.b[0])
    1320
    1321          # doesn't work in Py3:
    1322
    1323          #for comparison in ["abc", 5, 7.3, True, [], ()]:
    1324          #    none = root.b[1]
    1325          #    self.assertTrue(none < comparison, "%s (%s) should be < %s" %
    1326          #                 (none, type(none), comparison) )
    1327          #    self.assertTrue(comparison > none, "%s should be > %s (%s)" %
    1328          #                 (comparison, none, type(none)) )
    1329
    1330 -    def test_dataelement_xsi(self):
    1331          el = objectify.DataElement(1, _xsi="string")
    1332          self.assertEqual(
    1333              el.get(XML_SCHEMA_INSTANCE_TYPE_ATTR),
    1334              'xsd:string')
    1335
    1336 -    def test_dataelement_xsi_nsmap(self):
    1337          el = objectify.DataElement(1, _xsi="string",
    1338                                     nsmap={'schema': XML_SCHEMA_NS})
    1339          self.assertEqual(
    1340              el.get(XML_SCHEMA_INSTANCE_TYPE_ATTR),
    1341              'schema:string')
    1342
    1343 -    def test_dataelement_xsi_prefix_error(self):
    1344          self.assertRaises(ValueError, objectify.DataElement, 1,
    1345                            _xsi="foo:string")
    1346
    1347 -    def test_pytype_annotation(self):
    1348          XML = self.XML
    1349          root = XML(_bytes('''\
    1350          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1351          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1352            <b>5</b>
    1353            <b>test</b>
    1354            <c>1.1</c>
    1355            <c>\uF8D2</c>
    1356            <x>true</x>
    1357            <n xsi:nil="true" />
    1358            <n></n>
    1359            <b xsi:type="double">5</b>
    1360            <b xsi:type="float">5</b>
    1361            <s xsi:type="string">23</s>
    1362            <s py:pytype="str">42</s>
    1363            <f py:pytype="float">300</f>
    1364            <l py:pytype="long">2</l>
    1365            <t py:pytype="TREE"></t>
    1366          </a>
    1367          '''))
    1368          objectify.annotate(root)
    1369
    1370          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1371                          for c in root.iterchildren() ]
    1372          self.assertEqual("int",   child_types[ 0])
    1373          self.assertEqual("str",   child_types[ 1])
    1374          self.assertEqual("float", child_types[ 2])
    1375          self.assertEqual("str",   child_types[ 3])
    1376          self.assertEqual("bool",  child_types[ 4])
    1377          self.assertEqual("NoneType",  child_types[ 5])
    1378          self.assertEqual(None,    child_types[ 6])
    1379          self.assertEqual("float", child_types[ 7])
    1380          self.assertEqual("float", child_types[ 8])
    1381          self.assertEqual("str",   child_types[ 9])
    1382          self.assertEqual("int",   child_types[10])
    1383          self.assertEqual("int",   child_types[11])
    1384          self.assertEqual("int",   child_types[12])
    1385          self.assertEqual(None,    child_types[13])
    1386
    1387          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1388
    1389 -    def test_pytype_annotation_empty(self):
    1390          XML = self.XML
    1391          root = XML(_bytes('''\
    1392          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1393          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1394            <n></n>
    1395          </a>
    1396          '''))
    1397          objectify.annotate(root)
    1398
    1399          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1400                          for c in root.iterchildren() ]
    1401          self.assertEqual(None,    child_types[0])
    1402
    1403          objectify.annotate(root, empty_pytype="str")
    1404
    1405          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1406                          for c in root.iterchildren() ]
    1407          self.assertEqual("str",    child_types[0])
    1408
    1409 -    def test_pytype_annotation_use_old(self):
    1410          XML = self.XML
    1411          root = XML(_bytes('''\
    1412          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1413          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1414            <b>5</b>
    1415            <b>test</b>
    1416            <c>1.1</c>
    1417            <c>\uF8D2</c>
    1418            <x>true</x>
    1419            <n xsi:nil="true" />
    1420            <n></n>
    1421            <b xsi:type="double">5</b>
    1422            <b xsi:type="float">5</b>
    1423            <s xsi:type="string">23</s>
    1424            <s py:pytype="str">42</s>
    1425            <f py:pytype="float">300</f>
    1426            <l py:pytype="long">2</l>
    1427            <t py:pytype="TREE"></t>
    1428          </a>
    1429          '''))
    1430          objectify.annotate(root, ignore_old=False)
    1431
    1432          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1433                          for c in root.iterchildren() ]
    1434          self.assertEqual("int",   child_types[ 0])
    1435          self.assertEqual("str",   child_types[ 1])
    1436          self.assertEqual("float", child_types[ 2])
    1437          self.assertEqual("str",   child_types[ 3])
    1438          self.assertEqual("bool",  child_types[ 4])
    1439          self.assertEqual("NoneType",  child_types[ 5])
    1440          self.assertEqual(None,    child_types[ 6])
    1441          self.assertEqual("float", child_types[ 7])
    1442          self.assertEqual("float", child_types[ 8])
    1443          self.assertEqual("str",   child_types[ 9])
    1444          self.assertEqual("str",   child_types[10])
    1445          self.assertEqual("float", child_types[11])
    1446          self.assertEqual("int",   child_types[12])
    1447          self.assertEqual(TREE_PYTYPE,  child_types[13])
    1448
    1449          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1450
    1451 -    def test_pytype_xsitype_annotation(self):
    1452          XML = self.XML
    1453          root = XML(_bytes('''\
    1454          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1455          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1456            <b>5</b>
    1457            <b>test</b>
    1458            <c>1.1</c>
    1459            <c>\uF8D2</c>
    1460            <x>true</x>
    1461            <n xsi:nil="true" />
    1462            <n></n>
    1463            <b xsi:type="double">5</b>
    1464            <b xsi:type="float">5</b>
    1465            <s xsi:type="string">23</s>
    1466            <s py:pytype="str">42</s>
    1467            <f py:pytype="float">300</f>
    1468            <l py:pytype="long">2</l>
    1469            <t py:pytype="TREE"></t>
    1470          </a>
    1471          '''))
    1472          objectify.annotate(root, ignore_old=False, ignore_xsi=False,
    1473                             annotate_xsi=1, annotate_pytype=1)
    1474
    1475          # check py annotations
    1476          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1477                          for c in root.iterchildren() ]
    1478          self.assertEqual("int",   child_types[ 0])
    1479          self.assertEqual("str",   child_types[ 1])
    1480          self.assertEqual("float", child_types[ 2])
    1481          self.assertEqual("str",   child_types[ 3])
    1482          self.assertEqual("bool",  child_types[ 4])
    1483          self.assertEqual("NoneType",  child_types[ 5])
    1484          self.assertEqual(None,    child_types[ 6])
    1485          self.assertEqual("float", child_types[ 7])
    1486          self.assertEqual("float", child_types[ 8])
    1487          self.assertEqual("str",   child_types[ 9])
    1488          self.assertEqual("str",   child_types[10])
    1489          self.assertEqual("float",   child_types[11])
    1490          self.assertEqual("int",     child_types[12])
    1491          self.assertEqual(TREE_PYTYPE,  child_types[13])
    1492
    1493          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1494
    1495          child_xsitypes = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1496                          for c in root.iterchildren() ]
    1497
    1498          # check xsi annotations
    1499          child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1500                          for c in root.iterchildren() ]
    1501          self.assertEqual("xsd:integer", child_types[ 0])
    1502          self.assertEqual("xsd:string",  child_types[ 1])
    1503          self.assertEqual("xsd:double",  child_types[ 2])
    1504          self.assertEqual("xsd:string",  child_types[ 3])
    1505          self.assertEqual("xsd:boolean", child_types[ 4])
    1506          self.assertEqual(None,          child_types[ 5])
    1507          self.assertEqual(None,          child_types[ 6])
    1508          self.assertEqual("xsd:double",  child_types[ 7])
    1509          self.assertEqual("xsd:float",   child_types[ 8])
    1510          self.assertEqual("xsd:string",  child_types[ 9])
    1511          self.assertEqual("xsd:string",  child_types[10])
    1512          self.assertEqual("xsd:double",  child_types[11])
    1513          self.assertEqual("xsd:integer", child_types[12])
    1514          self.assertEqual(None,  child_types[13])
    1515
    1516          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1517
    1518 -    def test_xsiannotate_use_old(self):
    1519          XML = self.XML
    1520          root = XML(_bytes('''\
    1521          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1522          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1523            <b>5</b>
    1524            <b>test</b>
    1525            <c>1.1</c>
    1526            <c>\uF8D2</c>
    1527            <x>true</x>
    1528            <n xsi:nil="true" />
    1529            <n></n>
    1530            <b xsi:type="double">5</b>
    1531            <b xsi:type="float">5</b>
    1532            <s xsi:type="string">23</s>
    1533            <s py:pytype="str">42</s>
    1534            <f py:pytype="float">300</f>
    1535            <l py:pytype="long">2</l>
    1536            <t py:pytype="TREE"></t>
    1537          </a>
    1538          '''))
    1539          objectify.xsiannotate(root, ignore_old=False)
    1540
    1541          child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1542                          for c in root.iterchildren() ]
    1543          self.assertEqual("xsd:integer", child_types[ 0])
    1544          self.assertEqual("xsd:string",  child_types[ 1])
    1545          self.assertEqual("xsd:double",  child_types[ 2])
    1546          self.assertEqual("xsd:string",  child_types[ 3])
    1547          self.assertEqual("xsd:boolean", child_types[ 4])
    1548          self.assertEqual(None,          child_types[ 5])
    1549          self.assertEqual(None,          child_types[ 6])
    1550          self.assertEqual("xsd:double",  child_types[ 7])
    1551          self.assertEqual("xsd:float",   child_types[ 8])
    1552          self.assertEqual("xsd:string",  child_types[ 9])
    1553          self.assertEqual("xsd:string",  child_types[10])
    1554          self.assertEqual("xsd:double",  child_types[11])
    1555          self.assertEqual("xsd:integer", child_types[12])
    1556          self.assertEqual(None,          child_types[13])
    1557
    1558 -    def test_pyannotate_ignore_old(self):
    1559          XML = self.XML
    1560          root = XML(_bytes('''\
    1561          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1562          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1563            <b>5</b>
    1564            <b>test</b>
    1565            <c>1.1</c>
    1566            <c>\uF8D2</c>
    1567            <x>true</x>
    1568            <n xsi:nil="true" />
    1569            <n></n>
    1570            <b xsi:type="double">5</b>
    1571            <b xsi:type="float">5</b>
    1572            <s xsi:type="string">23</s>
    1573            <s py:pytype="str">42</s>
    1574            <f py:pytype="float">300</f>
    1575            <l py:pytype="long">2</l>
    1576            <t py:pytype="TREE"></t>
    1577          </a>
    1578          '''))
    1579          objectify.pyannotate(root, ignore_old=True)
    1580
    1581          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1582                          for c in root.iterchildren() ]
    1583          self.assertEqual("int",   child_types[ 0])
    1584          self.assertEqual("str",   child_types[ 1])
    1585          self.assertEqual("float", child_types[ 2])
    1586          self.assertEqual("str",   child_types[ 3])
    1587          self.assertEqual("bool",  child_types[ 4])
    1588          self.assertEqual("NoneType",  child_types[ 5])
    1589          self.assertEqual(None,    child_types[ 6])
    1590          self.assertEqual("float", child_types[ 7])
    1591          self.assertEqual("float", child_types[ 8])
    1592          self.assertEqual("str",   child_types[ 9])
    1593          self.assertEqual("int",   child_types[10])
    1594          self.assertEqual("int",   child_types[11])
    1595          self.assertEqual("int",   child_types[12])
    1596          self.assertEqual(None,    child_types[13])
    1597
    1598          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1599
    1600 -    def test_pyannotate_empty(self):
    1601          XML = self.XML
    1602          root = XML('''\
    1603          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1604          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1605            <n></n>
    1606          </a>
    1607          ''')
    1608          objectify.pyannotate(root)
    1609
    1610          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1611                          for c in root.iterchildren() ]
    1612          self.assertEqual(None,    child_types[0])
    1613
    1614          objectify.annotate(root, empty_pytype="str")
    1615
    1616          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1617                          for c in root.iterchildren() ]
    1618          self.assertEqual("str",    child_types[0])
    1619
    1620 -    def test_pyannotate_use_old(self):
    1621          XML = self.XML
    1622          root = XML('''\
    1623          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1624          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1625            <b>5</b>
    1626            <b>test</b>
    1627            <c>1.1</c>
    1628            <c>\uF8D2</c>
    1629            <x>true</x>
    1630            <n xsi:nil="true" />
    1631            <n></n>
    1632            <b xsi:type="double">5</b>
    1633            <b xsi:type="float">5</b>
    1634            <s xsi:type="string">23</s>
    1635            <s py:pytype="str">42</s>
    1636            <f py:pytype="float">300</f>
    1637            <l py:pytype="long">2</l>
    1638            <t py:pytype="TREE"></t>
    1639          </a>
    1640          ''')
    1641          objectify.pyannotate(root)
    1642
    1643          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1644                          for c in root.iterchildren() ]
    1645          self.assertEqual("int",   child_types[ 0])
    1646          self.assertEqual("str",   child_types[ 1])
    1647          self.assertEqual("float", child_types[ 2])
    1648          self.assertEqual("str",   child_types[ 3])
    1649          self.assertEqual("bool",  child_types[ 4])
    1650          self.assertEqual("NoneType",  child_types[ 5])
    1651          self.assertEqual(None,    child_types[ 6])
    1652          self.assertEqual("float", child_types[ 7])
    1653          self.assertEqual("float", child_types[ 8])
    1654          self.assertEqual("str",   child_types[ 9])
    1655          self.assertEqual("str",   child_types[10])
    1656          self.assertEqual("float", child_types[11])
    1657          self.assertEqual("int",   child_types[12])
    1658          self.assertEqual(TREE_PYTYPE, child_types[13])
    1659
    1660          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1661
    1662 -    def test_xsiannotate_ignore_old(self):
    1663          XML = self.XML
    1664          root = XML(_bytes('''\
    1665          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1666          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1667            <b>5</b>
    1668            <b>test</b>
    1669            <c>1.1</c>
    1670            <c>\uF8D2</c>
    1671            <x>true</x>
    1672            <n xsi:nil="true" />
    1673            <n></n>
    1674            <b xsi:type="double">5</b>
    1675            <b xsi:type="float">5</b>
    1676            <s xsi:type="string">23</s>
    1677            <s py:pytype="str">42</s>
    1678            <f py:pytype="float">300</f>
    1679            <l py:pytype="long">2</l>
    1680            <t py:pytype="TREE"></t>
    1681          </a>
    1682          '''))
    1683          objectify.xsiannotate(root, ignore_old=True)
    1684
    1685          child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1686                          for c in root.iterchildren() ]
    1687          self.assertEqual("xsd:integer", child_types[ 0])
    1688          self.assertEqual("xsd:string",  child_types[ 1])
    1689          self.assertEqual("xsd:double",  child_types[ 2])
    1690          self.assertEqual("xsd:string",  child_types[ 3])
    1691          self.assertEqual("xsd:boolean", child_types[ 4])
    1692          self.assertEqual(None,          child_types[ 5])
    1693          self.assertEqual(None,          child_types[ 6])
    1694          self.assertEqual("xsd:integer", child_types[ 7])
    1695          self.assertEqual("xsd:integer", child_types[ 8])
    1696          self.assertEqual("xsd:integer", child_types[ 9])
    1697          self.assertEqual("xsd:string",  child_types[10])
    1698          self.assertEqual("xsd:double",  child_types[11])
    1699          self.assertEqual("xsd:integer", child_types[12])
    1700          self.assertEqual(None,          child_types[13])
    1701
    1702          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1703
    1704 -    def test_deannotate(self):
    1705          XML = self.XML
    1706          root = XML(_bytes('''\
    1707          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1708          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1709            <b>5</b>
    1710            <b>test</b>
    1711            <c>1.1</c>
    1712            <c>\uF8D2</c>
    1713            <x>true</x>
    1714            <n xsi:nil="true" />
    1715            <n></n>
    1716            <b xsi:type="double">5</b>
    1717            <b xsi:type="float">5</b>
    1718            <s xsi:type="string">23</s>
    1719            <s py:pytype="str">42</s>
    1720            <f py:pytype="float">300</f>
    1721            <l py:pytype="long">2</l>
    1722            <t py:pytype="TREE"></t>
    1723          </a>
    1724          '''))
    1725          objectify.deannotate(root)
    1726
    1727          for c in root.getiterator():
    1728              self.assertEqual(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
    1729              self.assertEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
    1730
    1731          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1732
    1733 -    def test_xsinil_deannotate(self):
    1734          XML = self.XML
    1735          root = XML(_bytes('''\
    1736          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1737          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1738            <b>5</b>
    1739            <b>test</b>
    1740            <c>1.1</c>
    1741            <c>\uF8D2</c>
    1742            <x>true</x>
    1743            <n xsi:nil="true" />
    1744            <n></n>
    1745            <b xsi:type="double">5</b>
    1746            <b xsi:type="float">5</b>
    1747            <s xsi:type="string">23</s>
    1748            <s py:pytype="str">42</s>
    1749            <f py:pytype="float">300</f>
    1750            <l py:pytype="long">2</l>
    1751            <t py:pytype="TREE"></t>
    1752          </a>
    1753          '''))
    1754          objectify.annotate(
    1755              root, ignore_old=False, ignore_xsi=False, annotate_xsi=True,
    1756              empty_pytype='str', empty_type='string')
    1757          objectify.deannotate(root, pytype=False, xsi=False, xsi_nil=True)
    1758
    1759          child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1760                          for c in root.iterchildren() ]
    1761          self.assertEqual("xsd:integer",  child_types[ 0])
    1762          self.assertEqual("xsd:string",   child_types[ 1])
    1763          self.assertEqual("xsd:double",   child_types[ 2])
    1764          self.assertEqual("xsd:string",   child_types[ 3])
    1765          self.assertEqual("xsd:boolean",  child_types[ 4])
    1766          self.assertEqual(None,           child_types[ 5])
    1767          self.assertEqual("xsd:string",   child_types[ 6])
    1768          self.assertEqual("xsd:double",   child_types[ 7])
    1769          self.assertEqual("xsd:float",    child_types[ 8])
    1770          self.assertEqual("xsd:string",   child_types[ 9])
    1771          self.assertEqual("xsd:string",   child_types[10])
    1772          self.assertEqual("xsd:double",    child_types[11])
    1773          self.assertEqual("xsd:integer",  child_types[12])
    1774          self.assertEqual(None,           child_types[13])
    1775
    1776          self.assertEqual(None, root.n.get(XML_SCHEMA_NIL_ATTR))
    1777
    1778          for c in root.iterchildren():
    1779              self.assertNotEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
    1780              # these have no equivalent in xsi:type
    1781              if (c.get(objectify.PYTYPE_ATTRIBUTE) not in [TREE_PYTYPE,
    1782                  "NoneType"]):
    1783                  self.assertNotEqual(
    1784                      None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
    1785
    1786 -    def test_xsitype_deannotate(self):
    1787          XML = self.XML
    1788          root = XML(_bytes('''\
    1789          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1790          xmlns:py="http://codespeak.net/lxml/objectify/pytype"
    1791          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    1792            <b>5</b>
    1793            <b>test</b>
    1794            <c>1.1</c>
    1795            <c>\uF8D2</c>
    1796            <x>true</x>
    1797            <n xsi:nil="true" />
    1798            <n></n>
    1799            <b xsi:type="xsd:double">5</b>
    1800            <b xsi:type="xsd:float">5</b>
    1801            <s xsi:type="xsd:string">23</s>
    1802            <s py:pytype="str">42</s>
    1803            <f py:pytype="float">300</f>
    1804            <l py:pytype="long">2</l>
    1805            <t py:pytype="TREE"></t>
    1806          </a>
    1807          '''))
    1808          objectify.annotate(root)
    1809          objectify.deannotate(root, pytype=False)
    1810
    1811          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1812                          for c in root.iterchildren() ]
    1813          self.assertEqual("int",   child_types[ 0])
    1814          self.assertEqual("str",   child_types[ 1])
    1815          self.assertEqual("float", child_types[ 2])
    1816          self.assertEqual("str",   child_types[ 3])
    1817          self.assertEqual("bool",  child_types[ 4])
    1818          self.assertEqual("NoneType",  child_types[ 5])
    1819          self.assertEqual(None,    child_types[ 6])
    1820          self.assertEqual("float", child_types[ 7])
    1821          self.assertEqual("float", child_types[ 8])
    1822          self.assertEqual("str",   child_types[ 9])
    1823          self.assertEqual("int",   child_types[10])
    1824          self.assertEqual("int",   child_types[11])
    1825          self.assertEqual("int",   child_types[12])
    1826          self.assertEqual(None,    child_types[13])
    1827
    1828          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1829
    1830          for c in root.getiterator():
    1831              self.assertEqual(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
    1832
    1833 -    def test_pytype_deannotate(self):
    1834          XML = self.XML
    1835          root = XML(_bytes('''\
    1836          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1837          xmlns:py="http://codespeak.net/lxml/objectify/pytype"
    1838          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    1839            <b xsi:type="xsd:int">5</b>
    1840            <b xsi:type="xsd:string">test</b>
    1841            <c xsi:type="xsd:float">1.1</c>
    1842            <c xsi:type="xsd:string">\uF8D2</c>
    1843            <x xsi:type="xsd:boolean">true</x>
    1844            <n xsi:nil="true" />
    1845            <n></n>
    1846            <b xsi:type="xsd:double">5</b>
    1847            <b xsi:type="xsd:float">5</b>
    1848            <s xsi:type="xsd:string">23</s>
    1849            <s xsi:type="xsd:string">42</s>
    1850            <f xsi:type="xsd:float">300</f>
    1851            <l xsi:type="xsd:long">2</l>
    1852            <t py:pytype="TREE"></t>
    1853          </a>
    1854          '''))
    1855          objectify.annotate(root)
    1856          objectify.deannotate(root, xsi=False)
    1857
    1858          child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1859                          for c in root.iterchildren() ]
    1860          self.assertEqual("xsd:int",      child_types[ 0])
    1861          self.assertEqual("xsd:string",   child_types[ 1])
    1862          self.assertEqual("xsd:float",    child_types[ 2])
    1863          self.assertEqual("xsd:string",   child_types[ 3])
    1864          self.assertEqual("xsd:boolean",  child_types[ 4])
    1865          self.assertEqual(None,           child_types[ 5])
    1866          self.assertEqual(None,           child_types[ 6])
    1867          self.assertEqual("xsd:double",   child_types[ 7])
    1868          self.assertEqual("xsd:float",    child_types[ 8])
    1869          self.assertEqual("xsd:string",   child_types[ 9])
    1870          self.assertEqual("xsd:string",   child_types[10])
    1871          self.assertEqual("xsd:float",    child_types[11])
    1872          self.assertEqual("xsd:long",     child_types[12])
    1873          self.assertEqual(None,           child_types[13])
    1874
    1875          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1876
    1877          for c in root.getiterator():
    1878              self.assertEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
    1879
    1880 -    def test_change_pytype_attribute(self):
    1881          XML = self.XML
    1882
    1883          xml = _bytes('''\
    1884          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    1885            <b>5</b>
    1886            <b>test</b>
    1887            <c>1.1</c>
    1888            <c>\uF8D2</c>
    1889            <x>true</x>
    1890            <n xsi:nil="true" />
    1891            <n></n>
    1892            <b xsi:type="double">5</b>
    1893          </a>
    1894          ''')
    1895
    1896          pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
    1897          objectify.set_pytype_attribute_tag("{TEST}test")
    1898
    1899          root = XML(xml)
    1900          objectify.annotate(root)
    1901
    1902          attribs = root.xpath("//@py:%s" % pytype_name,
    1903                               namespaces={"py" : pytype_ns})
    1904          self.assertEqual(0, len(attribs))
    1905          attribs = root.xpath("//@py:test",
    1906                               namespaces={"py" : "TEST"})
    1907          self.assertEqual(7, len(attribs))
    1908
    1909          objectify.set_pytype_attribute_tag()
    1910          pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
    1911
    1912          self.assertNotEqual("test", pytype_ns.lower())
    1913          self.assertNotEqual("test", pytype_name.lower())
    1914
    1915          root = XML(xml)
    1916          attribs = root.xpath("//@py:%s" % pytype_name,
    1917                               namespaces={"py" : pytype_ns})
    1918          self.assertEqual(0, len(attribs))
    1919
    1920          objectify.annotate(root)
    1921          attribs = root.xpath("//@py:%s" % pytype_name,
    1922                               namespaces={"py" : pytype_ns})
    1923          self.assertEqual(7, len(attribs))
    1924
    1925 -    def test_registered_types(self):
    1926          orig_types = objectify.getRegisteredTypes()
    1927          orig_types[0].unregister()
    1928          self.assertEqual(orig_types[1:], objectify.getRegisteredTypes())
    1929
    1930          class NewType(objectify.ObjectifiedDataElement):
    1931              pass
    1932
    1933          def checkMyType(s):
    1934              return True
    1935
    1936          pytype = objectify.PyType("mytype", checkMyType, NewType)
    1937          self.assertTrue(pytype not in objectify.getRegisteredTypes())
    1938          pytype.register()
    1939          self.assertTrue(pytype in objectify.getRegisteredTypes())
    1940          pytype.unregister()
    1941          self.assertTrue(pytype not in objectify.getRegisteredTypes())
    1942
    1943          pytype.register(before = [objectify.getRegisteredTypes()[0].name])
    1944          self.assertEqual(pytype, objectify.getRegisteredTypes()[0])
    1945          pytype.unregister()
    1946
    1947          pytype.register(after = [objectify.getRegisteredTypes()[0].name])
    1948          self.assertNotEqual(pytype, objectify.getRegisteredTypes()[0])
    1949          pytype.unregister()
    1950
    1951          self.assertRaises(ValueError, pytype.register,
    1952                            before = [objectify.getRegisteredTypes()[0].name],
    1953                            after  = [objectify.getRegisteredTypes()[1].name])
    1954
    1955 -    def test_registered_type_stringify(self):
    1956          from datetime import datetime
    1957          def parse_date(value):
    1958              if len(value) != 14:
    1959                  raise ValueError(value)
    1960              Y = int(value[0:4])
    1961              M = int(value[4:6])
    1962              D = int(value[6:8])
    1963              h = int(value[8:10])
    1964              m = int(value[10:12])
    1965              s = int(value[12:14])
    1966              return datetime(Y, M, D, h, m, s)
    1967
    1968          def stringify_date(date):
    1969              return date.strftime("%Y%m%d%H%M%S")
    1970
    1971          class DatetimeElement(objectify.ObjectifiedDataElement):
    1972              def pyval(self):
    1973                  return parse_date(self.text)
    1974              pyval = property(pyval)
    1975
    1976          datetime_type = objectify.PyType(
    1977              "datetime", parse_date, DatetimeElement, stringify_date)
    1978          datetime_type.xmlSchemaTypes = "dateTime"
    1979          datetime_type.register()
    1980
    1981          NAMESPACE = "http://foo.net/xmlns"
    1982          NAMESPACE_MAP = {'ns': NAMESPACE}
    1983
    1984          r = objectify.Element("{%s}root" % NAMESPACE, nsmap=NAMESPACE_MAP)
    1985          time = datetime.now()
    1986          r.date = time
    1987
    1988          self.assertTrue(isinstance(r.date, DatetimeElement))
    1989          self.assertTrue(isinstance(r.date.pyval, datetime))
    1990
    1991          self.assertEqual(r.date.pyval, parse_date(stringify_date(time)))
    1992          self.assertEqual(r.date.text, stringify_date(time))
    1993
    1994          r.date = objectify.E.date(time)
    1995
    1996          self.assertTrue(isinstance(r.date, DatetimeElement))
    1997          self.assertTrue(isinstance(r.date.pyval, datetime))
    1998
    1999          self.assertEqual(r.date.pyval, parse_date(stringify_date(time)))
    2000          self.assertEqual(r.date.text, stringify_date(time))
    2001
    2002          date = objectify.DataElement(time)
    2003
    2004          self.assertTrue(isinstance(date, DatetimeElement))
    2005          self.assertTrue(isinstance(date.pyval, datetime))
    2006
    2007          self.assertEqual(date.pyval, parse_date(stringify_date(time)))
    2008          self.assertEqual(date.text, stringify_date(time))
    2009
    2010 -    def test_object_path(self):
    2011          root = self.XML(xml_str)
    2012          path = objectify.ObjectPath( "root.c1.c2" )
    2013          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2014          self.assertEqual(root.c1.c2.text, path(root).text)
    2015
    2016 -    def test_object_path_list(self):
    2017          root = self.XML(xml_str)
    2018          path = objectify.ObjectPath( ['root', 'c1', 'c2'] )
    2019          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2020          self.assertEqual(root.c1.c2.text, path(root).text)
    2021
    2022 -    def test_object_path_fail(self):
    2023          root = self.XML(xml_str)
    2024          path = objectify.ObjectPath( "root.c1.c99" )
    2025          self.assertRaises(AttributeError, path, root)
    2026
    2027 -    def test_object_path_default_absolute(self):
    2028          root = self.XML(xml_str)
    2029          path = objectify.ObjectPath( "root.c1.c99" )
    2030          self.assertEqual(None, path(root, None))
    2031          path = objectify.ObjectPath( "root.c99.c2" )
    2032          self.assertEqual(None, path(root, None))
    2033          path = objectify.ObjectPath( "notroot.c99.c2" )
    2034          self.assertEqual(None, path(root, None))
    2035
    2036 -    def test_object_path_default_relative(self):
    2037          root = self.XML(xml_str)
    2038          path = objectify.ObjectPath( ".c1.c99" )
    2039          self.assertEqual(None, path(root, None))
    2040          path = objectify.ObjectPath( ".c99.c2" )
    2041          self.assertEqual(None, path(root, None))
    2042
    2043 -    def test_object_path_syntax(self):
    2044          root = self.XML(xml_str)
    2045          path = objectify.ObjectPath("root .    {objectified}c1.   c2")
    2046          self.assertEqual(root.c1.c2.text, path(root).text)
    2047
    2048          path = objectify.ObjectPath("   root.{objectified}  c1.c2  [ 0 ]   ")
    2049          self.assertEqual(root.c1.c2.text, path(root).text)
    2050
    2051 -    def test_object_path_fail_parse_empty(self):
    2052          self.assertRaises(ValueError, objectify.ObjectPath, "")
    2053
    2054 -    def test_object_path_fail_parse_empty_list(self):
    2055          self.assertRaises(ValueError, objectify.ObjectPath, [])
    2056
    2057 -    def test_object_path_hasattr(self):
    2058          root = self.XML(xml_str)
    2059          path = objectify.ObjectPath( "root" )
    2060          self.assertTrue(path.hasattr(root))
    2061          path = objectify.ObjectPath( "root.c1" )
    2062          self.assertTrue(path.hasattr(root))
    2063          path = objectify.ObjectPath( "root.c1.c2" )
    2064          self.assertTrue(path.hasattr(root))
    2065          path = objectify.ObjectPath( "root.c1.{otherNS}c2" )
    2066          self.assertTrue(path.hasattr(root))
    2067          path = objectify.ObjectPath( "root.c1.c2[1]" )
    2068          self.assertTrue(path.hasattr(root))
    2069          path = objectify.ObjectPath( "root.c1.c2[2]" )
    2070          self.assertTrue(path.hasattr(root))
    2071          path = objectify.ObjectPath( "root.c1.c2[3]" )
    2072          self.assertFalse(path.hasattr(root))
    2073          path = objectify.ObjectPath( "root.c1[1].c2" )
    2074          self.assertFalse(path.hasattr(root))
    2075
    2076 -    def test_object_path_dot(self):
    2077          root = self.XML(xml_str)
    2078          path = objectify.ObjectPath( "." )
    2079          self.assertEqual(root.c1.c2.text, path(root).c1.c2.text)
    2080
    2081 -    def test_object_path_dot_list(self):
    2082          root = self.XML(xml_str)
    2083          path = objectify.ObjectPath( [''] )
    2084          self.assertEqual(root.c1.c2.text, path(root).c1.c2.text)
    2085
    2086 -    def test_object_path_dot_root(self):
    2087          root = self.XML(xml_str)
    2088          path = objectify.ObjectPath( ".c1.c2" )
    2089          self.assertEqual(root.c1.c2.text, path(root).text)
    2090
    2091 -    def test_object_path_dot_root_list(self):
    2092          root = self.XML(xml_str)
    2093          path = objectify.ObjectPath( ['', 'c1', 'c2'] )
    2094          self.assertEqual(root.c1.c2.text, path(root).text)
    2095
    2096 -    def test_object_path_index(self):
    2097          root = self.XML(xml_str)
    2098          path = objectify.ObjectPath( "root.c1[0].c2[0]" )
    2099          self.assertEqual(root.c1.c2.text, path(root).text)
    2100
    2101          path = objectify.ObjectPath( "root.c1[0].c2" )
    2102          self.assertEqual(root.c1.c2.text, path(root).text)
    2103
    2104          path = objectify.ObjectPath( "root.c1[0].c2[1]" )
    2105          self.assertEqual(root.c1.c2[1].text, path(root).text)
    2106
    2107          path = objectify.ObjectPath( "root.c1.c2[2]" )
    2108          self.assertEqual(root.c1.c2[2].text, path(root).text)
    2109
    2110          path = objectify.ObjectPath( "root.c1.c2[-1]" )
    2111          self.assertEqual(root.c1.c2[-1].text, path(root).text)
    2112
    2113          path = objectify.ObjectPath( "root.c1.c2[-3]" )
    2114          self.assertEqual(root.c1.c2[-3].text, path(root).text)
    2115
    2116 -    def test_object_path_index_list(self):
    2117          root = self.XML(xml_str)
    2118          path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[0]'] )
    2119          self.assertEqual(root.c1.c2.text, path(root).text)
    2120
    2121          path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[2]'] )
    2122          self.assertEqual(root.c1.c2[2].text, path(root).text)
    2123
    2124          path = objectify.ObjectPath( ['root', 'c1', 'c2[2]'] )
    2125          self.assertEqual(root.c1.c2[2].text, path(root).text)
    2126
    2127          path = objectify.ObjectPath( ['root', 'c1', 'c2[-1]'] )
    2128          self.assertEqual(root.c1.c2[-1].text, path(root).text)
    2129
    2130          path = objectify.ObjectPath( ['root', 'c1', 'c2[-3]'] )
    2131          self.assertEqual(root.c1.c2[-3].text, path(root).text)
    2132
    2133 -    def test_object_path_index_fail_parse(self):
    2134          self.assertRaises(ValueError, objectify.ObjectPath,
    2135                            "root.c1[0].c2[-1-2]")
    2136          self.assertRaises(ValueError, objectify.ObjectPath,
    2137                            ['root', 'c1[0]', 'c2[-1-2]'])
    2138
    2139          self.assertRaises(ValueError, objectify.ObjectPath,
    2140                            "root[2].c1.c2")
    2141          self.assertRaises(ValueError, objectify.ObjectPath,
    2142                            ['root[2]', 'c1', 'c2'])
    2143
    2144          self.assertRaises(ValueError, objectify.ObjectPath,
    2145                            [])
    2146          self.assertRaises(ValueError, objectify.ObjectPath,
    2147                            ['', '', ''])
    2148
    2149 -    def test_object_path_index_fail_lookup(self):
    2150          root = self.XML(xml_str)
    2151          path = objectify.ObjectPath("root.c1[9999].c2")
    2152          self.assertRaises(AttributeError, path, root)
    2153
    2154          path = objectify.ObjectPath("root.c1[0].c2[9999]")
    2155          self.assertRaises(AttributeError, path, root)
    2156
    2157          path = objectify.ObjectPath(".c1[9999].c2[0]")
    2158          self.assertRaises(AttributeError, path, root)
    2159
    2160          path = objectify.ObjectPath("root.c1[-2].c2")
    2161          self.assertRaises(AttributeError, path, root)
    2162
    2163          path = objectify.ObjectPath("root.c1[0].c2[-4]")
    2164          self.assertRaises(AttributeError, path, root)
    2165
    2166 -    def test_object_path_ns(self):
    2167          root = self.XML(xml_str)
    2168          path = objectify.ObjectPath( "{objectified}root.c1.c2" )
    2169          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2170          path = objectify.ObjectPath( "{objectified}root.{objectified}c1.c2" )
    2171          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2172          path = objectify.ObjectPath( "root.{objectified}c1.{objectified}c2" )
    2173          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2174          path = objectify.ObjectPath( "root.c1.{objectified}c2" )
    2175          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2176          path = objectify.ObjectPath( "root.c1.{otherNS}c2" )
    2177          self.assertEqual(getattr(root.c1, '{otherNS}c2').text,
    2178                            path.find(root).text)
    2179
    2180 -    def test_object_path_ns_list(self):
    2181          root = self.XML(xml_str)
    2182          path = objectify.ObjectPath( ['{objectified}root', 'c1', 'c2'] )
    2183          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2184          path = objectify.ObjectPath( ['{objectified}root', '{objectified}c1', 'c2'] )
    2185          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2186          path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2'] )
    2187          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2188          path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2[2]'] )
    2189          self.assertEqual(root.c1.c2[2].text, path.find(root).text)
    2190          path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2'] )
    2191          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2192          path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2[2]'] )
    2193          self.assertEqual(root.c1.c2[2].text, path.find(root).text)
    2194          path = objectify.ObjectPath( ['root', 'c1', '{otherNS}c2'] )
    2195          self.assertEqual(getattr(root.c1, '{otherNS}c2').text,
    2196                            path.find(root).text)
    2197
    2198 -    def test_object_path_set(self):
    2199          root = self.XML(xml_str)
    2200          path = objectify.ObjectPath( "root.c1.c2" )
    2201          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2202          self.assertEqual("1", root.c1.c2[1].text)
    2203
    2204          new_value = "my new value"
    2205          path.setattr(root, new_value)
    2206
    2207          self.assertEqual(new_value, root.c1.c2.text)
    2208          self.assertEqual(new_value, path(root).text)
    2209          self.assertEqual("1", root.c1.c2[1].text)
    2210
    2211 -    def test_object_path_set_element(self):
    2212          root = self.XML(xml_str)
    2213          path = objectify.ObjectPath( "root.c1.c2" )
    2214          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2215          self.assertEqual("1", root.c1.c2[1].text)
    2216
    2217          new_el = self.Element("{objectified}test")
    2218          etree.SubElement(new_el, "{objectified}sub", myattr="ATTR").a = "TEST"
    2219          path.setattr(root, new_el.sub)
    2220
    2221          self.assertEqual("ATTR", root.c1.c2.get("myattr"))
    2222          self.assertEqual("TEST", root.c1.c2.a.text)
    2223          self.assertEqual("TEST", path(root).a.text)
    2224          self.assertEqual("1", root.c1.c2[1].text)
    2225
    2226 -    def test_object_path_set_create(self):
    2227          root = self.XML(xml_str)
    2228          path = objectify.ObjectPath( "root.c1.c99" )
    2229          self.assertRaises(AttributeError, path.find, root)
    2230
    2231          new_value = "my new value"
    2232          path.setattr(root, new_value)
    2233
    2234          self.assertEqual(1, len(root.c1.c99))
    2235          self.assertEqual(new_value, root.c1.c99.text)
    2236          self.assertEqual(new_value, path(root).text)
    2237
    2238 -    def test_object_path_set_create_element(self):
    2239          root = self.XML(xml_str)
    2240          path = objectify.ObjectPath( "root.c1.c99" )
    2241          self.assertRaises(AttributeError, path.find, root)
    2242
    2243          new_el = self.Element("{objectified}test")
    2244          etree.SubElement(new_el, "{objectified}sub", myattr="ATTR").a = "TEST"
    2245          path.setattr(root, new_el.sub)
    2246
    2247          self.assertEqual(1, len(root.c1.c99))
    2248          self.assertEqual("ATTR", root.c1.c99.get("myattr"))
    2249          self.assertEqual("TEST", root.c1.c99.a.text)
    2250          self.assertEqual("TEST", path(root).a.text)
    2251
    2252 -    def test_object_path_set_create_list(self):
    2253          root = self.XML(xml_str)
    2254          path = objectify.ObjectPath( "root.c1.c99" )
    2255          self.assertRaises(AttributeError, path.find, root)
    2256
    2257          new_el = self.Element("{objectified}test")
    2258          new_el.a = ["TEST1", "TEST2"]
    2259          new_el.a[0].set("myattr", "ATTR1")
    2260          new_el.a[1].set("myattr", "ATTR2")
    2261
    2262          path.setattr(root, list(new_el.a))
    2263
    2264          self.assertEqual(2, len(root.c1.c99))
    2265          self.assertEqual("ATTR1", root.c1.c99[0].get("myattr"))
    2266          self.assertEqual("TEST1", root.c1.c99[0].text)
    2267          self.assertEqual("ATTR2", root.c1.c99[1].get("myattr"))
    2268          self.assertEqual("TEST2", root.c1.c99[1].text)
    2269          self.assertEqual("TEST1", path(root).text)
    2270
    2271 -    def test_object_path_addattr(self):
    2272          root = self.XML(xml_str)
    2273          path = objectify.ObjectPath( "root.c1.c2" )
    2274          self.assertEqual(3, len(root.c1.c2))
    2275          path.addattr(root, "test")
    2276          self.assertEqual(4, len(root.c1.c2))
    2277          self.assertEqual(["0", "1", "2", "test"],
    2278                            [el.text for el in root.c1.c2])
    2279
    2280 -    def test_object_path_addattr_element(self):
    2281          root = self.XML(xml_str)
    2282          path = objectify.ObjectPath( "root.c1.c2" )
    2283          self.assertEqual(3, len(root.c1.c2))
    2284
    2285          new_el = self.Element("{objectified}test")
    2286          etree.SubElement(new_el, "{objectified}sub").a = "TEST"
    2287
    2288          path.addattr(root, new_el.sub)
    2289          self.assertEqual(4, len(root.c1.c2))
    2290          self.assertEqual("TEST", root.c1.c2[3].a.text)
    2291          self.assertEqual(["0", "1", "2"],
    2292                            [el.text for el in root.c1.c2[:3]])
    2293
    2294 -    def test_object_path_addattr_create(self):
    2295          root = self.XML(xml_str)
    2296          path = objectify.ObjectPath( "root.c1.c99" )
    2297          self.assertRaises(AttributeError, path.find, root)
    2298
    2299          new_value = "my new value"
    2300          path.addattr(root, new_value)
    2301
    2302          self.assertEqual(1, len(root.c1.c99))
    2303          self.assertEqual(new_value, root.c1.c99.text)
    2304          self.assertEqual(new_value, path(root).text)
    2305
    2306 -    def test_object_path_addattr_create_element(self):
    2307          root = self.XML(xml_str)
    2308          path = objectify.ObjectPath( "root.c1.c99" )
    2309          self.assertRaises(AttributeError, path.find, root)
    2310
    2311          new_el = self.Element("{objectified}test")
    2312          etree.SubElement(new_el, "{objectified}sub", myattr="ATTR").a = "TEST"
    2313
    2314          path.addattr(root, new_el.sub)
    2315          self.assertEqual(1, len(root.c1.c99))
    2316          self.assertEqual("TEST", root.c1.c99.a.text)
    2317          self.assertEqual("TEST", path(root).a.text)
    2318          self.assertEqual("ATTR", root.c1.c99.get("myattr"))
    2319
    2320 -    def test_object_path_addattr_create_list(self):
    2321          root = self.XML(xml_str)
    2322          path = objectify.ObjectPath( "root.c1.c99" )
    2323          self.assertRaises(AttributeError, path.find, root)
    2324
    2325          new_el = self.Element("{objectified}test")
    2326          new_el.a = ["TEST1", "TEST2"]
    2327
    2328          self.assertEqual(2, len(new_el.a))
    2329
    2330          path.addattr(root, list(new_el.a))
    2331          self.assertEqual(2, len(root.c1.c99))
    2332          self.assertEqual("TEST1", root.c1.c99.text)
    2333          self.assertEqual("TEST2", path(root)[1].text)
    2334
    2335 -    def test_descendant_paths(self):
    2336          root = self.XML(xml_str)
    2337          self.assertEqual(
    2338              ['{objectified}root', '{objectified}root.c1',
    2339               '{objectified}root.c1.c2',
    2340               '{objectified}root.c1.c2[1]', '{objectified}root.c1.c2[2]',
    2341               '{objectified}root.c1.{otherNS}c2', '{objectified}root.c1.{}c2'],
    2342              root.descendantpaths())
    2343
    2344 -    def test_descendant_paths_child(self):
    2345          root = self.XML(xml_str)
    2346          self.assertEqual(
    2347              ['{objectified}c1', '{objectified}c1.c2',
    2348               '{objectified}c1.c2[1]', '{objectified}c1.c2[2]',
    2349               '{objectified}c1.{otherNS}c2', '{objectified}c1.{}c2'],
    2350              root.c1.descendantpaths())
    2351
    2352 -    def test_descendant_paths_prefix(self):
    2353          root = self.XML(xml_str)
    2354          self.assertEqual(
    2355              ['root.{objectified}c1', 'root.{objectified}c1.c2',
    2356               'root.{objectified}c1.c2[1]', 'root.{objectified}c1.c2[2]',
    2357               'root.{objectified}c1.{otherNS}c2',
    2358               'root.{objectified}c1.{}c2'],
    2359              root.c1.descendantpaths('root'))
    2360
    2361 -    def test_pickle(self):
    2362          import pickle
    2363
    2364          root = self.XML(xml_str)
    2365          out = BytesIO()
    2366          pickle.dump(root, out)
    2367
    2368          new_root = pickle.loads(out.getvalue())
    2369          self.assertEqual(
    2370              etree.tostring(new_root),
    2371              etree.tostring(root))
    2372
    2373 -    def test_pickle_elementtree(self):
    2374          import pickle
    2375
    2376          tree = etree.ElementTree(self.XML(xml_str + "<?my pi?>"))
    2377          out = BytesIO()
    2378          pickle.dump(tree, out)
    2379
    2380          new_tree = pickle.loads(out.getvalue())
    2381          self.assertTrue(isinstance(new_tree, etree._ElementTree))
    2382          self.assertEqual(
    2383              etree.tostring(new_tree),
    2384              etree.tostring(tree))
    2385
    2386 -    def test_pickle_intelement(self):
    2387          self._test_pickle('<x>42</x>')
    2388          self._test_pickle(objectify.DataElement(42))
    2389
    2390 -    def test_pickle_floattelement(self):
    2391          self._test_pickle('<x>42.0</x>')
    2392          self._test_pickle(objectify.DataElement(42.0))
    2393
    2394 -    def test_pickle_strelement(self):
    2395          self._test_pickle('<x>Pickle me!</x>')
    2396          self._test_pickle(objectify.DataElement('Pickle me!'))
    2397
    2398 -    def test_pickle_boolelement(self):
    2399          self._test_pickle('<x>true</x>')
    2400          self._test_pickle('<x>false</x>')
    2401          self._test_pickle(objectify.DataElement(True))
    2402          self._test_pickle(objectify.DataElement(False))
    2403
    2404 -    def test_pickle_noneelement(self):
    2405          self._test_pickle('''
    2406  <x xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>''')
    2407          self._test_pickle(objectify.DataElement(None))
    2408
    2409 -    def _test_pickle(self, stringOrElt):
    2410          import pickle
    2411          if isinstance(stringOrElt, (etree._Element, etree._ElementTree)):
    2412              elt = stringOrElt
    2413          else:
    2414              elt = self.XML(stringOrElt)
    2415          out = BytesIO()
    2416          pickle.dump(elt, out)
    2417
    2418          new_elt = pickle.loads(out.getvalue())
    2419          self.assertEqual(
    2420              etree.tostring(new_elt),
    2421              etree.tostring(elt))
    2422
    2423      # E-Factory tests, need to use sub-elements as root element is always
    2424      # type-looked-up as ObjectifiedElement (no annotations)
    2425 -    def test_efactory_int(self):
    2426          E = objectify.E
    2427          root = E.root(E.val(23))
    2428          self.assertTrue(isinstance(root.val, objectify.IntElement))
    2429
    2430 -    def test_efactory_float(self):
    2431          E = objectify.E
    2432          root = E.root(E.val(233.23))
    2433          self.assertTrue(isinstance(root.val, objectify.FloatElement))
    2434
    2435 -    def test_efactory_str(self):
    2436          E = objectify.E
    2437          root = E.root(E.val("what?"))
    2438          self.assertTrue(isinstance(root.val, objectify.StringElement))
    2439
    2440 -    def test_efactory_unicode(self):
    2441          E = objectify.E
    2442          root = E.root(E.val(_str("blöödy häll", encoding="ISO-8859-1")))
    2443          self.assertTrue(isinstance(root.val, objectify.StringElement))
    2444
    2445 -    def test_efactory_bool(self):
    2446          E = objectify.E
    2447          root = E.root(E.val(True))
    2448          self.assertTrue(isinstance(root.val, objectify.BoolElement))
    2449
    2450 -    def test_efactory_none(self):
    2451          E = objectify.E
    2452          root = E.root(E.val(None))
    2453          self.assertTrue(isinstance(root.val, objectify.NoneElement))
    2454
    2455 -    def test_efactory_value_concatenation(self):
    2456          E = objectify.E
    2457          root = E.root(E.val(1, "foo", 2.0, "bar ", True, None))
    2458          self.assertTrue(isinstance(root.val, objectify.StringElement))
    2459
    2460 -    def test_efactory_attrib(self):
    2461          E = objectify.E
    2462          root = E.root(foo="bar")
    2463          self.assertEqual(root.get("foo"), "bar")
    2464
    2465 -    def test_efactory_nested(self):
    2466          E = objectify.E
    2467          DataElement = objectify.DataElement
    2468          root = E.root("text", E.sub(E.subsub()), "tail", DataElement(1),
    2469                        DataElement(2.0))
    2470          self.assertTrue(isinstance(root, objectify.ObjectifiedElement))
    2471          self.assertEqual(root.text, "text")
    2472          self.assertTrue(isinstance(root.sub, objectify.ObjectifiedElement))
    2473          self.assertEqual(root.sub.tail, "tail")
    2474          self.assertTrue(isinstance(root.sub.subsub, objectify.StringElement))
    2475          self.assertEqual(len(root.value), 2)
    2476          self.assertTrue(isinstance(root.value[0], objectify.IntElement))
    2477          self.assertTrue(isinstance(root.value[1], objectify.FloatElement))
    2478
    2479 -    def test_efactory_subtype(self):
    2480          class Attribute(objectify.ObjectifiedDataElement):
    2481              def __init__(self):
    2482                  objectify.ObjectifiedDataElement.__init__(self)
    2483                  self.set("datatype", "TYPE")
    2484                  self.set("range", "0.,1.")
    2485
    2486          attr = Attribute()
    2487          self.assertEqual(attr.text, None)
    2488          self.assertEqual(attr.get("datatype"), "TYPE")
    2489          self.assertEqual(attr.get("range"), "0.,1.")
    2490
    2491 -    def test_XML_base_url_docinfo(self):
    2492          root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2493          docinfo = root.getroottree().docinfo
    2494          self.assertEqual(docinfo.URL, "http://no/such/url")
    2495
    2496 -    def test_XML_set_base_url_docinfo(self):
    2497          root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2498          docinfo = root.getroottree().docinfo
    2499          self.assertEqual(docinfo.URL, "http://no/such/url")
    2500          docinfo.URL = "https://secret/url"
    2501          self.assertEqual(docinfo.URL, "https://secret/url")
    2502
    2503 -    def test_parse_stringio_base_url(self):
    2504          tree = objectify.parse(BytesIO("<root/>"), base_url="http://no/such/url")
    2505          docinfo = tree.docinfo
    2506          self.assertEqual(docinfo.URL, "http://no/such/url")
    2507
    2508 -    def test_parse_base_url_docinfo(self):
    2509          tree = objectify.parse(fileInTestDir('include/test_xinclude.xml'),
    2510                                 base_url="http://no/such/url")
    2511          docinfo = tree.docinfo
    2512          self.assertEqual(docinfo.URL, "http://no/such/url")
    2513
    2514 -    def test_xml_base(self):
    2515          root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2516          self.assertEqual(root.base, "http://no/such/url")
    2517          self.assertEqual(
    2518              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2519          root.base = "https://secret/url"
    2520          self.assertEqual(root.base, "https://secret/url")
    2521          self.assertEqual(
    2522              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2523              "https://secret/url")
    2524
    2525 -    def test_xml_base_attribute(self):
    2526          root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2527          self.assertEqual(root.base, "http://no/such/url")
    2528          self.assertEqual(
    2529              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2530          root.set('{http://www.w3.org/XML/1998/namespace}base',
    2531                   "https://secret/url")
    2532          self.assertEqual(root.base, "https://secret/url")
    2533          self.assertEqual(
    2534              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2535              "https://secret/url")
    2536
    2537 -    def test_standard_lookup(self):
    2538          XML = self.XML
    2539
    2540          xml = _bytes('''\
    2541          <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    2542            <i>5</i>
    2543            <i>-5</i>
    2544            <l>4294967296</l>
    2545            <l>-4294967296</l>
    2546            <f>1.1</f>
    2547            <b>true</b>
    2548            <b>false</b>
    2549            <s>Strange things happen, where strings collide</s>
    2550            <s>True</s>
    2551            <s>False</s>
    2552            <s>t</s>
    2553            <s>f</s>
    2554            <s></s>
    2555            <s>None</s>
    2556            <n xsi:nil="true" />
    2557          </root>
    2558          ''')
    2559          root = XML(xml)
    2560
    2561          for i in root.i:
    2562              self.assertTrue(isinstance(i, objectify.IntElement))
    2563          for l in root.l:
    2564              self.assertTrue(isinstance(l, objectify.IntElement))
    2565          for f in root.f:
    2566              self.assertTrue(isinstance(f, objectify.FloatElement))
    2567          for b in root.b:
    2568              self.assertTrue(isinstance(b, objectify.BoolElement))
    2569          self.assertEqual(True,  root.b[0])
    2570          self.assertEqual(False, root.b[1])
    2571          for s in root.s:
    2572              self.assertTrue(isinstance(s, objectify.StringElement))
    2573          self.assertTrue(isinstance(root.n, objectify.NoneElement))
    2574          self.assertEqual(None, root.n)
    2575
    2576 -def test_suite():
    2577      suite = unittest.TestSuite()
    2578      suite.addTests([unittest.makeSuite(ObjectifyTestCase)])
    2579      suite.addTests(doctest.DocTestSuite(objectify))
    2580      if sys.version_info >= (2,4):
    2581          suite.addTests(
    2582              [make_doctest('../../../doc/objectify.txt')])
    2583      return suite
    2584
    2585  if __name__ == '__main__':
    2586      print('to test use test.py %s' % __file__)
    2587