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_type_float_precision(self):
    1020          # test not losing precision by shortened float str() value
    1021          # repr(2.305064300557): '2.305064300557'
    1022          # str(2.305064300557): '2.30506430056'
    1023          # "%57.54f" % 2.305064300557:
    1024          #     ' 2.305064300556999956626214043353684246540069580078125000'
    1025          Element = self.Element
    1026          root = Element("{objectified}root")
    1027          s = "2.305064300557"
    1028          root.f = float(s)
    1029          self.assertTrue(isinstance(root.f, objectify.FloatElement))
    1030          self.assertEqual(root.f.text, s)
    1031          self.assertEqual(root.f.pyval, float(s))
    1032
    1033 -    def test_type_float_instantiation_precision(self):
    1034          # test precision preservation for FloatElement instantiation
    1035          s = "2.305064300557"
    1036          self.assertEqual(objectify.FloatElement(s), float(s))
    1037
    1038 -    def test_type_float_precision_consistency(self):
    1039          # test consistent FloatElement values for the different instantiation
    1040          # possibilities
    1041          Element = self.Element
    1042          root = Element("{objectified}root")
    1043          s = "2.305064300557"
    1044          f = float(s)
    1045          float_elem = objectify.FloatElement(s)
    1046          float_data_elem = objectify.DataElement(f)
    1047          root.float_child = float(f)
    1048          self.assertTrue(f == float_elem == float_data_elem == root.float_child)
    1049
    1050 -    def test_data_element_float_precision(self):
    1051          # test not losing precision by shortened float str() value
    1052          f = 2305064300557.0
    1053          value = objectify.DataElement(f)
    1054          self.assertTrue(isinstance(value, objectify.FloatElement))
    1055          self.assertEqual(value, f)
    1056
    1057 -    def test_data_element_float_hash_repr(self):
    1058          # test not losing precision by shortened float str() value
    1059          f = 2305064300557.0
    1060          value = objectify.DataElement(f)
    1061          self.assertEqual(hash(value), hash(f))
    1062
    1063 -    def test_data_element_xsitypes(self):
    1064          for xsi, objclass in xsitype2objclass.items():
    1065              # 1 is a valid value for all ObjectifiedDataElement classes
    1066              pyval = 1
    1067              value = objectify.DataElement(pyval, _xsi=xsi)
    1068              self.assertTrue(isinstance(value, objclass),
    1069                           "DataElement(%s, _xsi='%s') returns %s, expected %s"
    1070                           % (pyval, xsi, type(value), objclass))
    1071
    1072 -    def test_data_element_xsitypes_xsdprefixed(self):
    1073          for xsi, objclass in xsitype2objclass.items():
    1074              # 1 is a valid value for all ObjectifiedDataElement classes
    1075              pyval = 1
    1076              value = objectify.DataElement(pyval, _xsi="xsd:%s" % xsi)
    1077              self.assertTrue(isinstance(value, objclass),
    1078                           "DataElement(%s, _xsi='%s') returns %s, expected %s"
    1079                           % (pyval, xsi, type(value), objclass))
    1080
    1081 -    def test_data_element_xsitypes_prefixed(self):
    1082          for xsi, objclass in xsitype2objclass.items():
    1083              # 1 is a valid value for all ObjectifiedDataElement classes
    1084              self.assertRaises(ValueError, objectify.DataElement, 1,
    1085                                _xsi="foo:%s" % xsi)
    1086
    1087 -    def test_data_element_pytypes(self):
    1088          for pytype, objclass in pytype2objclass.items():
    1089              # 1 is a valid value for all ObjectifiedDataElement classes
    1090              pyval = 1
    1091              value = objectify.DataElement(pyval, _pytype=pytype)
    1092              self.assertTrue(isinstance(value, objclass),
    1093                           "DataElement(%s, _pytype='%s') returns %s, expected %s"
    1094                           % (pyval, pytype, type(value), objclass))
    1095
    1096 -    def test_data_element_pytype_none(self):
    1097          pyval = 1
    1098          pytype = "NoneType"
    1099          objclass = objectify.NoneElement
    1100          value = objectify.DataElement(pyval, _pytype=pytype)
    1101          self.assertTrue(isinstance(value, objclass),
    1102                       "DataElement(%s, _pytype='%s') returns %s, expected %s"
    1103                       % (pyval, pytype, type(value), objclass))
    1104          self.assertEqual(value.text, None)
    1105          self.assertEqual(value.pyval, None)
    1106
    1107 -    def test_data_element_pytype_none_compat(self):
    1108          # pre-2.0 lxml called NoneElement "none"
    1109          pyval = 1
    1110          pytype = "none"
    1111          objclass = objectify.NoneElement
    1112          value = objectify.DataElement(pyval, _pytype=pytype)
    1113          self.assertTrue(isinstance(value, objclass),
    1114                       "DataElement(%s, _pytype='%s') returns %s, expected %s"
    1115                       % (pyval, pytype, type(value), objclass))
    1116          self.assertEqual(value.text, None)
    1117          self.assertEqual(value.pyval, None)
    1118
    1119 -    def test_type_unregistered(self):
    1120          Element = self.Element
    1121          SubElement = self.etree.SubElement
    1122          class MyFloat(float):
    1123              pass
    1124          root = Element("{objectified}root")
    1125          root.myfloat = MyFloat(5.5)
    1126          self.assertTrue(isinstance(root.myfloat, objectify.FloatElement))
    1127          self.assertEqual(root.myfloat.get(objectify.PYTYPE_ATTRIBUTE), None)
    1128
    1129 -    def test_data_element_unregistered(self):
    1130          class MyFloat(float):
    1131              pass
    1132          value = objectify.DataElement(MyFloat(5.5))
    1133          self.assertTrue(isinstance(value, objectify.FloatElement))
    1134          self.assertEqual(value, 5.5)
    1135          self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), None)
    1136
    1137 -    def test_schema_types(self):
    1138          XML = self.XML
    1139          root = XML('''\
    1140          <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    1141            <b xsi:type="boolean">true</b>
    1142            <b xsi:type="boolean">false</b>
    1143            <b xsi:type="boolean">1</b>
    1144            <b xsi:type="boolean">0</b>
    1145
    1146            <f xsi:type="float">5</f>
    1147            <f xsi:type="double">5</f>
    1148
    1149            <s xsi:type="string">5</s>
    1150            <s xsi:type="normalizedString">5</s>
    1151            <s xsi:type="token">5</s>
    1152            <s xsi:type="language">5</s>
    1153            <s xsi:type="Name">5</s>
    1154            <s xsi:type="NCName">5</s>
    1155            <s xsi:type="ID">5</s>
    1156            <s xsi:type="IDREF">5</s>
    1157            <s xsi:type="ENTITY">5</s>
    1158            <s xsi:type="NMTOKEN">5</s>
    1159
    1160            <l xsi:type="integer">5</l>
    1161            <l xsi:type="nonPositiveInteger">5</l>
    1162            <l xsi:type="negativeInteger">5</l>
    1163            <l xsi:type="long">5</l>
    1164            <l xsi:type="nonNegativeInteger">5</l>
    1165            <l xsi:type="unsignedLong">5</l>
    1166            <l xsi:type="unsignedInt">5</l>
    1167            <l xsi:type="positiveInteger">5</l>
    1168
    1169            <i xsi:type="int">5</i>
    1170            <i xsi:type="short">5</i>
    1171            <i xsi:type="byte">5</i>
    1172            <i xsi:type="unsignedShort">5</i>
    1173            <i xsi:type="unsignedByte">5</i>
    1174
    1175            <n xsi:nil="true"/>
    1176          </root>
    1177          ''')
    1178
    1179          for b in root.b:
    1180              self.assertTrue(isinstance(b, objectify.BoolElement))
    1181          self.assertEqual(True,  root.b[0])
    1182          self.assertEqual(False, root.b[1])
    1183          self.assertEqual(True,  root.b[2])
    1184          self.assertEqual(False, root.b[3])
    1185
    1186          for f in root.f:
    1187              self.assertTrue(isinstance(f, objectify.FloatElement))
    1188              self.assertEqual(5, f)
    1189
    1190          for s in root.s:
    1191              self.assertTrue(isinstance(s, objectify.StringElement))
    1192              self.assertEqual("5", s)
    1193
    1194          for i in root.i:
    1195              self.assertTrue(isinstance(i, objectify.IntElement))
    1196              self.assertEqual(5, i)
    1197
    1198          for l in root.l:
    1199              self.assertTrue(isinstance(l, objectify.IntElement))
    1200              self.assertEqual(5, i)
    1201
    1202          self.assertTrue(isinstance(root.n, objectify.NoneElement))
    1203          self.assertEqual(None, root.n)
    1204
    1205 -    def test_schema_types_prefixed(self):
    1206          XML = self.XML
    1207          root = XML('''\
    1208          <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1209          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    1210            <b xsi:type="xsd:boolean">true</b>
    1211            <b xsi:type="xsd:boolean">false</b>
    1212            <b xsi:type="xsd:boolean">1</b>
    1213            <b xsi:type="xsd:boolean">0</b>
    1214
    1215            <f xsi:type="xsd:float">5</f>
    1216            <f xsi:type="xsd:double">5</f>
    1217
    1218            <s xsi:type="xsd:string">5</s>
    1219            <s xsi:type="xsd:normalizedString">5</s>
    1220            <s xsi:type="xsd:token">5</s>
    1221            <s xsi:type="xsd:language">5</s>
    1222            <s xsi:type="xsd:Name">5</s>
    1223            <s xsi:type="xsd:NCName">5</s>
    1224            <s xsi:type="xsd:ID">5</s>
    1225            <s xsi:type="xsd:IDREF">5</s>
    1226            <s xsi:type="xsd:ENTITY">5</s>
    1227            <s xsi:type="xsd:NMTOKEN">5</s>
    1228
    1229            <l xsi:type="xsd:integer">5</l>
    1230            <l xsi:type="xsd:nonPositiveInteger">5</l>
    1231            <l xsi:type="xsd:negativeInteger">5</l>
    1232            <l xsi:type="xsd:long">5</l>
    1233            <l xsi:type="xsd:nonNegativeInteger">5</l>
    1234            <l xsi:type="xsd:unsignedLong">5</l>
    1235            <l xsi:type="xsd:unsignedInt">5</l>
    1236            <l xsi:type="xsd:positiveInteger">5</l>
    1237
    1238            <i xsi:type="xsd:int">5</i>
    1239            <i xsi:type="xsd:short">5</i>
    1240            <i xsi:type="xsd:byte">5</i>
    1241            <i xsi:type="xsd:unsignedShort">5</i>
    1242            <i xsi:type="xsd:unsignedByte">5</i>
    1243
    1244            <n xsi:nil="true"/>
    1245          </root>
    1246          ''')
    1247
    1248          for b in root.b:
    1249              self.assertTrue(isinstance(b, objectify.BoolElement))
    1250          self.assertEqual(True,  root.b[0])
    1251          self.assertEqual(False, root.b[1])
    1252          self.assertEqual(True,  root.b[2])
    1253          self.assertEqual(False, root.b[3])
    1254
    1255          for f in root.f:
    1256              self.assertTrue(isinstance(f, objectify.FloatElement))
    1257              self.assertEqual(5, f)
    1258
    1259          for s in root.s:
    1260              self.assertTrue(isinstance(s, objectify.StringElement))
    1261              self.assertEqual("5", s)
    1262
    1263          for i in root.i:
    1264              self.assertTrue(isinstance(i, objectify.IntElement))
    1265              self.assertEqual(5, i)
    1266
    1267          for l in root.l:
    1268              self.assertTrue(isinstance(l, objectify.IntElement))
    1269              self.assertEqual(5, l)
    1270
    1271          self.assertTrue(isinstance(root.n, objectify.NoneElement))
    1272          self.assertEqual(None, root.n)
    1273
    1274 -    def test_type_str_sequence(self):
    1275          XML = self.XML
    1276          root = XML(_bytes('<root><b>why</b><b>try</b></root>'))
    1277          strs = [ str(s) for s in root.b ]
    1278          self.assertEqual(["why", "try"],
    1279                            strs)
    1280
    1281 -    def test_type_str_cmp(self):
    1282          XML = self.XML
    1283          root = XML(_bytes('<root><b>test</b><b>taste</b><b></b><b/></root>'))
    1284          self.assertFalse(root.b[0] <  root.b[1])
    1285          self.assertFalse(root.b[0] <= root.b[1])
    1286          self.assertFalse(root.b[0] == root.b[1])
    1287
    1288          self.assertTrue(root.b[0] != root.b[1])
    1289          self.assertTrue(root.b[0] >= root.b[1])
    1290          self.assertTrue(root.b[0] >  root.b[1])
    1291
    1292          self.assertEqual(root.b[0], "test")
    1293          self.assertEqual("test", root.b[0])
    1294
    1295          self.assertEqual("", root.b[2])
    1296          self.assertEqual(root.b[2], "")
    1297          self.assertEqual("", root.b[3])
    1298          self.assertEqual(root.b[3], "")
    1299          self.assertEqual(root.b[2], root.b[3])
    1300
    1301          root.b = "test"
    1302          self.assertTrue(root.b)
    1303          root.b = ""
    1304          self.assertFalse(root.b)
    1305          self.assertEqual(root.b, "")
    1306          self.assertEqual("", root.b)
    1307
    1308 -    def test_type_int_cmp(self):
    1309          XML = self.XML
    1310          root = XML(_bytes('<root><b>5</b><b>6</b></root>'))
    1311          self.assertTrue(root.b[0] <  root.b[1])
    1312          self.assertTrue(root.b[0] <= root.b[1])
    1313          self.assertTrue(root.b[0] != root.b[1])
    1314
    1315          self.assertFalse(root.b[0] == root.b[1])
    1316          self.assertFalse(root.b[0] >= root.b[1])
    1317          self.assertFalse(root.b[0] >  root.b[1])
    1318
    1319          self.assertEqual(root.b[0], 5)
    1320          self.assertEqual(5, root.b[0])
    1321          self.assertNotEqual(root.b[0], "5")
    1322
    1323          root.b = 5
    1324          self.assertTrue(root.b)
    1325          root.b = 0
    1326          self.assertFalse(root.b)
    1327
    1328      # float + long share the NumberElement implementation with int
    1329
    1330 -    def test_type_bool_cmp(self):
    1331          XML = self.XML
    1332          root = XML(_bytes('<root><b>false</b><b>true</b></root>'))
    1333          self.assertTrue(root.b[0] <  root.b[1])
    1334          self.assertTrue(root.b[0] <= root.b[1])
    1335          self.assertTrue(root.b[0] != root.b[1])
    1336
    1337          self.assertFalse(root.b[0] == root.b[1])
    1338          self.assertFalse(root.b[0] >= root.b[1])
    1339          self.assertFalse(root.b[0] >  root.b[1])
    1340
    1341          self.assertFalse(root.b[0])
    1342          self.assertTrue(root.b[1])
    1343
    1344          self.assertEqual(root.b[0], False)
    1345          self.assertEqual(False, root.b[0])
    1346          self.assertTrue(root.b[0] <  5)
    1347          self.assertTrue(5 > root.b[0])
    1348
    1349          root.b = True
    1350          self.assertTrue(root.b)
    1351          root.b = False
    1352          self.assertFalse(root.b)
    1353
    1354 -    def test_type_none_cmp(self):
    1355          XML = self.XML
    1356          root = XML(_bytes("""
    1357          <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    1358            <b xsi:nil="true"></b><b xsi:nil="true"/>
    1359          </root>"""))
    1360          self.assertTrue(root.b[0] == root.b[1])
    1361          self.assertFalse(root.b[0])
    1362          self.assertEqual(root.b[0], None)
    1363          self.assertEqual(None, root.b[0])
    1364
    1365          # doesn't work in Py3:
    1366
    1367          #for comparison in ["abc", 5, 7.3, True, [], ()]:
    1368          #    none = root.b[1]
    1369          #    self.assertTrue(none < comparison, "%s (%s) should be < %s" %
    1370          #                 (none, type(none), comparison) )
    1371          #    self.assertTrue(comparison > none, "%s should be > %s (%s)" %
    1372          #                 (comparison, none, type(none)) )
    1373
    1374 -    def test_dataelement_xsi(self):
    1375          el = objectify.DataElement(1, _xsi="string")
    1376          self.assertEqual(
    1377              el.get(XML_SCHEMA_INSTANCE_TYPE_ATTR),
    1378              'xsd:string')
    1379
    1380 -    def test_dataelement_xsi_nsmap(self):
    1381          el = objectify.DataElement(1, _xsi="string",
    1382                                     nsmap={'schema': XML_SCHEMA_NS})
    1383          self.assertEqual(
    1384              el.get(XML_SCHEMA_INSTANCE_TYPE_ATTR),
    1385              'schema:string')
    1386
    1387 -    def test_dataelement_xsi_prefix_error(self):
    1388          self.assertRaises(ValueError, objectify.DataElement, 1,
    1389                            _xsi="foo:string")
    1390
    1391 -    def test_pytype_annotation(self):
    1392          XML = self.XML
    1393          root = XML(_bytes('''\
    1394          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1395          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1396            <b>5</b>
    1397            <b>test</b>
    1398            <c>1.1</c>
    1399            <c>\uF8D2</c>
    1400            <x>true</x>
    1401            <n xsi:nil="true" />
    1402            <n></n>
    1403            <b xsi:type="double">5</b>
    1404            <b xsi:type="float">5</b>
    1405            <s xsi:type="string">23</s>
    1406            <s py:pytype="str">42</s>
    1407            <f py:pytype="float">300</f>
    1408            <l py:pytype="long">2</l>
    1409            <t py:pytype="TREE"></t>
    1410          </a>
    1411          '''))
    1412          objectify.annotate(root)
    1413
    1414          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1415                          for c in root.iterchildren() ]
    1416          self.assertEqual("int",   child_types[ 0])
    1417          self.assertEqual("str",   child_types[ 1])
    1418          self.assertEqual("float", child_types[ 2])
    1419          self.assertEqual("str",   child_types[ 3])
    1420          self.assertEqual("bool",  child_types[ 4])
    1421          self.assertEqual("NoneType",  child_types[ 5])
    1422          self.assertEqual(None,    child_types[ 6])
    1423          self.assertEqual("float", child_types[ 7])
    1424          self.assertEqual("float", child_types[ 8])
    1425          self.assertEqual("str",   child_types[ 9])
    1426          self.assertEqual("int",   child_types[10])
    1427          self.assertEqual("int",   child_types[11])
    1428          self.assertEqual("int",   child_types[12])
    1429          self.assertEqual(None,    child_types[13])
    1430
    1431          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1432
    1433 -    def test_pytype_annotation_empty(self):
    1434          XML = self.XML
    1435          root = XML(_bytes('''\
    1436          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1437          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1438            <n></n>
    1439          </a>
    1440          '''))
    1441          objectify.annotate(root)
    1442
    1443          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1444                          for c in root.iterchildren() ]
    1445          self.assertEqual(None,    child_types[0])
    1446
    1447          objectify.annotate(root, empty_pytype="str")
    1448
    1449          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1450                          for c in root.iterchildren() ]
    1451          self.assertEqual("str",    child_types[0])
    1452
    1453 -    def test_pytype_annotation_use_old(self):
    1454          XML = self.XML
    1455          root = XML(_bytes('''\
    1456          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1457          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1458            <b>5</b>
    1459            <b>test</b>
    1460            <c>1.1</c>
    1461            <c>\uF8D2</c>
    1462            <x>true</x>
    1463            <n xsi:nil="true" />
    1464            <n></n>
    1465            <b xsi:type="double">5</b>
    1466            <b xsi:type="float">5</b>
    1467            <s xsi:type="string">23</s>
    1468            <s py:pytype="str">42</s>
    1469            <f py:pytype="float">300</f>
    1470            <l py:pytype="long">2</l>
    1471            <t py:pytype="TREE"></t>
    1472          </a>
    1473          '''))
    1474          objectify.annotate(root, ignore_old=False)
    1475
    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 -    def test_pytype_xsitype_annotation(self):
    1496          XML = self.XML
    1497          root = XML(_bytes('''\
    1498          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1499          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1500            <b>5</b>
    1501            <b>test</b>
    1502            <c>1.1</c>
    1503            <c>\uF8D2</c>
    1504            <x>true</x>
    1505            <n xsi:nil="true" />
    1506            <n></n>
    1507            <b xsi:type="double">5</b>
    1508            <b xsi:type="float">5</b>
    1509            <s xsi:type="string">23</s>
    1510            <s py:pytype="str">42</s>
    1511            <f py:pytype="float">300</f>
    1512            <l py:pytype="long">2</l>
    1513            <t py:pytype="TREE"></t>
    1514          </a>
    1515          '''))
    1516          objectify.annotate(root, ignore_old=False, ignore_xsi=False,
    1517                             annotate_xsi=1, annotate_pytype=1)
    1518
    1519          # check py annotations
    1520          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1521                          for c in root.iterchildren() ]
    1522          self.assertEqual("int",   child_types[ 0])
    1523          self.assertEqual("str",   child_types[ 1])
    1524          self.assertEqual("float", child_types[ 2])
    1525          self.assertEqual("str",   child_types[ 3])
    1526          self.assertEqual("bool",  child_types[ 4])
    1527          self.assertEqual("NoneType",  child_types[ 5])
    1528          self.assertEqual(None,    child_types[ 6])
    1529          self.assertEqual("float", child_types[ 7])
    1530          self.assertEqual("float", child_types[ 8])
    1531          self.assertEqual("str",   child_types[ 9])
    1532          self.assertEqual("str",   child_types[10])
    1533          self.assertEqual("float",   child_types[11])
    1534          self.assertEqual("int",     child_types[12])
    1535          self.assertEqual(TREE_PYTYPE,  child_types[13])
    1536
    1537          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1538
    1539          child_xsitypes = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1540                          for c in root.iterchildren() ]
    1541
    1542          # check xsi annotations
    1543          child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1544                          for c in root.iterchildren() ]
    1545          self.assertEqual("xsd:integer", child_types[ 0])
    1546          self.assertEqual("xsd:string",  child_types[ 1])
    1547          self.assertEqual("xsd:double",  child_types[ 2])
    1548          self.assertEqual("xsd:string",  child_types[ 3])
    1549          self.assertEqual("xsd:boolean", child_types[ 4])
    1550          self.assertEqual(None,          child_types[ 5])
    1551          self.assertEqual(None,          child_types[ 6])
    1552          self.assertEqual("xsd:double",  child_types[ 7])
    1553          self.assertEqual("xsd:float",   child_types[ 8])
    1554          self.assertEqual("xsd:string",  child_types[ 9])
    1555          self.assertEqual("xsd:string",  child_types[10])
    1556          self.assertEqual("xsd:double",  child_types[11])
    1557          self.assertEqual("xsd:integer", child_types[12])
    1558          self.assertEqual(None,  child_types[13])
    1559
    1560          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1561
    1562 -    def test_xsiannotate_use_old(self):
    1563          XML = self.XML
    1564          root = XML(_bytes('''\
    1565          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1566          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1567            <b>5</b>
    1568            <b>test</b>
    1569            <c>1.1</c>
    1570            <c>\uF8D2</c>
    1571            <x>true</x>
    1572            <n xsi:nil="true" />
    1573            <n></n>
    1574            <b xsi:type="double">5</b>
    1575            <b xsi:type="float">5</b>
    1576            <s xsi:type="string">23</s>
    1577            <s py:pytype="str">42</s>
    1578            <f py:pytype="float">300</f>
    1579            <l py:pytype="long">2</l>
    1580            <t py:pytype="TREE"></t>
    1581          </a>
    1582          '''))
    1583          objectify.xsiannotate(root, ignore_old=False)
    1584
    1585          child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1586                          for c in root.iterchildren() ]
    1587          self.assertEqual("xsd:integer", child_types[ 0])
    1588          self.assertEqual("xsd:string",  child_types[ 1])
    1589          self.assertEqual("xsd:double",  child_types[ 2])
    1590          self.assertEqual("xsd:string",  child_types[ 3])
    1591          self.assertEqual("xsd:boolean", child_types[ 4])
    1592          self.assertEqual(None,          child_types[ 5])
    1593          self.assertEqual(None,          child_types[ 6])
    1594          self.assertEqual("xsd:double",  child_types[ 7])
    1595          self.assertEqual("xsd:float",   child_types[ 8])
    1596          self.assertEqual("xsd:string",  child_types[ 9])
    1597          self.assertEqual("xsd:string",  child_types[10])
    1598          self.assertEqual("xsd:double",  child_types[11])
    1599          self.assertEqual("xsd:integer", child_types[12])
    1600          self.assertEqual(None,          child_types[13])
    1601
    1602 -    def test_pyannotate_ignore_old(self):
    1603          XML = self.XML
    1604          root = XML(_bytes('''\
    1605          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1606          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1607            <b>5</b>
    1608            <b>test</b>
    1609            <c>1.1</c>
    1610            <c>\uF8D2</c>
    1611            <x>true</x>
    1612            <n xsi:nil="true" />
    1613            <n></n>
    1614            <b xsi:type="double">5</b>
    1615            <b xsi:type="float">5</b>
    1616            <s xsi:type="string">23</s>
    1617            <s py:pytype="str">42</s>
    1618            <f py:pytype="float">300</f>
    1619            <l py:pytype="long">2</l>
    1620            <t py:pytype="TREE"></t>
    1621          </a>
    1622          '''))
    1623          objectify.pyannotate(root, ignore_old=True)
    1624
    1625          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1626                          for c in root.iterchildren() ]
    1627          self.assertEqual("int",   child_types[ 0])
    1628          self.assertEqual("str",   child_types[ 1])
    1629          self.assertEqual("float", child_types[ 2])
    1630          self.assertEqual("str",   child_types[ 3])
    1631          self.assertEqual("bool",  child_types[ 4])
    1632          self.assertEqual("NoneType",  child_types[ 5])
    1633          self.assertEqual(None,    child_types[ 6])
    1634          self.assertEqual("float", child_types[ 7])
    1635          self.assertEqual("float", child_types[ 8])
    1636          self.assertEqual("str",   child_types[ 9])
    1637          self.assertEqual("int",   child_types[10])
    1638          self.assertEqual("int",   child_types[11])
    1639          self.assertEqual("int",   child_types[12])
    1640          self.assertEqual(None,    child_types[13])
    1641
    1642          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1643
    1644 -    def test_pyannotate_empty(self):
    1645          XML = self.XML
    1646          root = XML('''\
    1647          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1648          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1649            <n></n>
    1650          </a>
    1651          ''')
    1652          objectify.pyannotate(root)
    1653
    1654          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1655                          for c in root.iterchildren() ]
    1656          self.assertEqual(None,    child_types[0])
    1657
    1658          objectify.annotate(root, empty_pytype="str")
    1659
    1660          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1661                          for c in root.iterchildren() ]
    1662          self.assertEqual("str",    child_types[0])
    1663
    1664 -    def test_pyannotate_use_old(self):
    1665          XML = self.XML
    1666          root = XML('''\
    1667          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1668          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1669            <b>5</b>
    1670            <b>test</b>
    1671            <c>1.1</c>
    1672            <c>\uF8D2</c>
    1673            <x>true</x>
    1674            <n xsi:nil="true" />
    1675            <n></n>
    1676            <b xsi:type="double">5</b>
    1677            <b xsi:type="float">5</b>
    1678            <s xsi:type="string">23</s>
    1679            <s py:pytype="str">42</s>
    1680            <f py:pytype="float">300</f>
    1681            <l py:pytype="long">2</l>
    1682            <t py:pytype="TREE"></t>
    1683          </a>
    1684          ''')
    1685          objectify.pyannotate(root)
    1686
    1687          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1688                          for c in root.iterchildren() ]
    1689          self.assertEqual("int",   child_types[ 0])
    1690          self.assertEqual("str",   child_types[ 1])
    1691          self.assertEqual("float", child_types[ 2])
    1692          self.assertEqual("str",   child_types[ 3])
    1693          self.assertEqual("bool",  child_types[ 4])
    1694          self.assertEqual("NoneType",  child_types[ 5])
    1695          self.assertEqual(None,    child_types[ 6])
    1696          self.assertEqual("float", child_types[ 7])
    1697          self.assertEqual("float", child_types[ 8])
    1698          self.assertEqual("str",   child_types[ 9])
    1699          self.assertEqual("str",   child_types[10])
    1700          self.assertEqual("float", child_types[11])
    1701          self.assertEqual("int",   child_types[12])
    1702          self.assertEqual(TREE_PYTYPE, child_types[13])
    1703
    1704          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1705
    1706 -    def test_xsiannotate_ignore_old(self):
    1707          XML = self.XML
    1708          root = XML(_bytes('''\
    1709          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1710          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1711            <b>5</b>
    1712            <b>test</b>
    1713            <c>1.1</c>
    1714            <c>\uF8D2</c>
    1715            <x>true</x>
    1716            <n xsi:nil="true" />
    1717            <n></n>
    1718            <b xsi:type="double">5</b>
    1719            <b xsi:type="float">5</b>
    1720            <s xsi:type="string">23</s>
    1721            <s py:pytype="str">42</s>
    1722            <f py:pytype="float">300</f>
    1723            <l py:pytype="long">2</l>
    1724            <t py:pytype="TREE"></t>
    1725          </a>
    1726          '''))
    1727          objectify.xsiannotate(root, ignore_old=True)
    1728
    1729          child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1730                          for c in root.iterchildren() ]
    1731          self.assertEqual("xsd:integer", child_types[ 0])
    1732          self.assertEqual("xsd:string",  child_types[ 1])
    1733          self.assertEqual("xsd:double",  child_types[ 2])
    1734          self.assertEqual("xsd:string",  child_types[ 3])
    1735          self.assertEqual("xsd:boolean", child_types[ 4])
    1736          self.assertEqual(None,          child_types[ 5])
    1737          self.assertEqual(None,          child_types[ 6])
    1738          self.assertEqual("xsd:integer", child_types[ 7])
    1739          self.assertEqual("xsd:integer", child_types[ 8])
    1740          self.assertEqual("xsd:integer", child_types[ 9])
    1741          self.assertEqual("xsd:string",  child_types[10])
    1742          self.assertEqual("xsd:double",  child_types[11])
    1743          self.assertEqual("xsd:integer", child_types[12])
    1744          self.assertEqual(None,          child_types[13])
    1745
    1746          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1747
    1748 -    def test_deannotate(self):
    1749          XML = self.XML
    1750          root = XML(_bytes('''\
    1751          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1752          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1753            <b>5</b>
    1754            <b>test</b>
    1755            <c>1.1</c>
    1756            <c>\uF8D2</c>
    1757            <x>true</x>
    1758            <n xsi:nil="true" />
    1759            <n></n>
    1760            <b xsi:type="double">5</b>
    1761            <b xsi:type="float">5</b>
    1762            <s xsi:type="string">23</s>
    1763            <s py:pytype="str">42</s>
    1764            <f py:pytype="float">300</f>
    1765            <l py:pytype="long">2</l>
    1766            <t py:pytype="TREE"></t>
    1767          </a>
    1768          '''))
    1769          objectify.deannotate(root)
    1770
    1771          for c in root.getiterator():
    1772              self.assertEqual(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
    1773              self.assertEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
    1774
    1775          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1776
    1777 -    def test_xsinil_deannotate(self):
    1778          XML = self.XML
    1779          root = XML(_bytes('''\
    1780          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1781          xmlns:py="http://codespeak.net/lxml/objectify/pytype">
    1782            <b>5</b>
    1783            <b>test</b>
    1784            <c>1.1</c>
    1785            <c>\uF8D2</c>
    1786            <x>true</x>
    1787            <n xsi:nil="true" />
    1788            <n></n>
    1789            <b xsi:type="double">5</b>
    1790            <b xsi:type="float">5</b>
    1791            <s xsi:type="string">23</s>
    1792            <s py:pytype="str">42</s>
    1793            <f py:pytype="float">300</f>
    1794            <l py:pytype="long">2</l>
    1795            <t py:pytype="TREE"></t>
    1796          </a>
    1797          '''))
    1798          objectify.annotate(
    1799              root, ignore_old=False, ignore_xsi=False, annotate_xsi=True,
    1800              empty_pytype='str', empty_type='string')
    1801          objectify.deannotate(root, pytype=False, xsi=False, xsi_nil=True)
    1802
    1803          child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1804                          for c in root.iterchildren() ]
    1805          self.assertEqual("xsd:integer",  child_types[ 0])
    1806          self.assertEqual("xsd:string",   child_types[ 1])
    1807          self.assertEqual("xsd:double",   child_types[ 2])
    1808          self.assertEqual("xsd:string",   child_types[ 3])
    1809          self.assertEqual("xsd:boolean",  child_types[ 4])
    1810          self.assertEqual(None,           child_types[ 5])
    1811          self.assertEqual("xsd:string",   child_types[ 6])
    1812          self.assertEqual("xsd:double",   child_types[ 7])
    1813          self.assertEqual("xsd:float",    child_types[ 8])
    1814          self.assertEqual("xsd:string",   child_types[ 9])
    1815          self.assertEqual("xsd:string",   child_types[10])
    1816          self.assertEqual("xsd:double",    child_types[11])
    1817          self.assertEqual("xsd:integer",  child_types[12])
    1818          self.assertEqual(None,           child_types[13])
    1819
    1820          self.assertEqual(None, root.n.get(XML_SCHEMA_NIL_ATTR))
    1821
    1822          for c in root.iterchildren():
    1823              self.assertNotEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
    1824              # these have no equivalent in xsi:type
    1825              if (c.get(objectify.PYTYPE_ATTRIBUTE) not in [TREE_PYTYPE,
    1826                  "NoneType"]):
    1827                  self.assertNotEqual(
    1828                      None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
    1829
    1830 -    def test_xsitype_deannotate(self):
    1831          XML = self.XML
    1832          root = XML(_bytes('''\
    1833          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1834          xmlns:py="http://codespeak.net/lxml/objectify/pytype"
    1835          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    1836            <b>5</b>
    1837            <b>test</b>
    1838            <c>1.1</c>
    1839            <c>\uF8D2</c>
    1840            <x>true</x>
    1841            <n xsi:nil="true" />
    1842            <n></n>
    1843            <b xsi:type="xsd:double">5</b>
    1844            <b xsi:type="xsd:float">5</b>
    1845            <s xsi:type="xsd:string">23</s>
    1846            <s py:pytype="str">42</s>
    1847            <f py:pytype="float">300</f>
    1848            <l py:pytype="long">2</l>
    1849            <t py:pytype="TREE"></t>
    1850          </a>
    1851          '''))
    1852          objectify.annotate(root)
    1853          objectify.deannotate(root, pytype=False)
    1854
    1855          child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
    1856                          for c in root.iterchildren() ]
    1857          self.assertEqual("int",   child_types[ 0])
    1858          self.assertEqual("str",   child_types[ 1])
    1859          self.assertEqual("float", child_types[ 2])
    1860          self.assertEqual("str",   child_types[ 3])
    1861          self.assertEqual("bool",  child_types[ 4])
    1862          self.assertEqual("NoneType",  child_types[ 5])
    1863          self.assertEqual(None,    child_types[ 6])
    1864          self.assertEqual("float", child_types[ 7])
    1865          self.assertEqual("float", child_types[ 8])
    1866          self.assertEqual("str",   child_types[ 9])
    1867          self.assertEqual("int",   child_types[10])
    1868          self.assertEqual("int",   child_types[11])
    1869          self.assertEqual("int",   child_types[12])
    1870          self.assertEqual(None,    child_types[13])
    1871
    1872          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1873
    1874          for c in root.getiterator():
    1875              self.assertEqual(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
    1876
    1877 -    def test_pytype_deannotate(self):
    1878          XML = self.XML
    1879          root = XML(_bytes('''\
    1880          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    1881          xmlns:py="http://codespeak.net/lxml/objectify/pytype"
    1882          xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    1883            <b xsi:type="xsd:int">5</b>
    1884            <b xsi:type="xsd:string">test</b>
    1885            <c xsi:type="xsd:float">1.1</c>
    1886            <c xsi:type="xsd:string">\uF8D2</c>
    1887            <x xsi:type="xsd:boolean">true</x>
    1888            <n xsi:nil="true" />
    1889            <n></n>
    1890            <b xsi:type="xsd:double">5</b>
    1891            <b xsi:type="xsd:float">5</b>
    1892            <s xsi:type="xsd:string">23</s>
    1893            <s xsi:type="xsd:string">42</s>
    1894            <f xsi:type="xsd:float">300</f>
    1895            <l xsi:type="xsd:long">2</l>
    1896            <t py:pytype="TREE"></t>
    1897          </a>
    1898          '''))
    1899          objectify.annotate(root)
    1900          objectify.deannotate(root, xsi=False)
    1901
    1902          child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
    1903                          for c in root.iterchildren() ]
    1904          self.assertEqual("xsd:int",      child_types[ 0])
    1905          self.assertEqual("xsd:string",   child_types[ 1])
    1906          self.assertEqual("xsd:float",    child_types[ 2])
    1907          self.assertEqual("xsd:string",   child_types[ 3])
    1908          self.assertEqual("xsd:boolean",  child_types[ 4])
    1909          self.assertEqual(None,           child_types[ 5])
    1910          self.assertEqual(None,           child_types[ 6])
    1911          self.assertEqual("xsd:double",   child_types[ 7])
    1912          self.assertEqual("xsd:float",    child_types[ 8])
    1913          self.assertEqual("xsd:string",   child_types[ 9])
    1914          self.assertEqual("xsd:string",   child_types[10])
    1915          self.assertEqual("xsd:float",    child_types[11])
    1916          self.assertEqual("xsd:long",     child_types[12])
    1917          self.assertEqual(None,           child_types[13])
    1918
    1919          self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
    1920
    1921          for c in root.getiterator():
    1922              self.assertEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
    1923
    1924 -    def test_change_pytype_attribute(self):
    1925          XML = self.XML
    1926
    1927          xml = _bytes('''\
    1928          <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    1929            <b>5</b>
    1930            <b>test</b>
    1931            <c>1.1</c>
    1932            <c>\uF8D2</c>
    1933            <x>true</x>
    1934            <n xsi:nil="true" />
    1935            <n></n>
    1936            <b xsi:type="double">5</b>
    1937          </a>
    1938          ''')
    1939
    1940          pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
    1941          objectify.set_pytype_attribute_tag("{TEST}test")
    1942
    1943          root = XML(xml)
    1944          objectify.annotate(root)
    1945
    1946          attribs = root.xpath("//@py:%s" % pytype_name,
    1947                               namespaces={"py" : pytype_ns})
    1948          self.assertEqual(0, len(attribs))
    1949          attribs = root.xpath("//@py:test",
    1950                               namespaces={"py" : "TEST"})
    1951          self.assertEqual(7, len(attribs))
    1952
    1953          objectify.set_pytype_attribute_tag()
    1954          pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
    1955
    1956          self.assertNotEqual("test", pytype_ns.lower())
    1957          self.assertNotEqual("test", pytype_name.lower())
    1958
    1959          root = XML(xml)
    1960          attribs = root.xpath("//@py:%s" % pytype_name,
    1961                               namespaces={"py" : pytype_ns})
    1962          self.assertEqual(0, len(attribs))
    1963
    1964          objectify.annotate(root)
    1965          attribs = root.xpath("//@py:%s" % pytype_name,
    1966                               namespaces={"py" : pytype_ns})
    1967          self.assertEqual(7, len(attribs))
    1968
    1969 -    def test_registered_types(self):
    1970          orig_types = objectify.getRegisteredTypes()
    1971          orig_types[0].unregister()
    1972          self.assertEqual(orig_types[1:], objectify.getRegisteredTypes())
    1973
    1974          class NewType(objectify.ObjectifiedDataElement):
    1975              pass
    1976
    1977          def checkMyType(s):
    1978              return True
    1979
    1980          pytype = objectify.PyType("mytype", checkMyType, NewType)
    1981          self.assertTrue(pytype not in objectify.getRegisteredTypes())
    1982          pytype.register()
    1983          self.assertTrue(pytype in objectify.getRegisteredTypes())
    1984          pytype.unregister()
    1985          self.assertTrue(pytype not in objectify.getRegisteredTypes())
    1986
    1987          pytype.register(before = [objectify.getRegisteredTypes()[0].name])
    1988          self.assertEqual(pytype, objectify.getRegisteredTypes()[0])
    1989          pytype.unregister()
    1990
    1991          pytype.register(after = [objectify.getRegisteredTypes()[0].name])
    1992          self.assertNotEqual(pytype, objectify.getRegisteredTypes()[0])
    1993          pytype.unregister()
    1994
    1995          self.assertRaises(ValueError, pytype.register,
    1996                            before = [objectify.getRegisteredTypes()[0].name],
    1997                            after  = [objectify.getRegisteredTypes()[1].name])
    1998
    1999 -    def test_registered_type_stringify(self):
    2000          from datetime import datetime
    2001          def parse_date(value):
    2002              if len(value) != 14:
    2003                  raise ValueError(value)
    2004              Y = int(value[0:4])
    2005              M = int(value[4:6])
    2006              D = int(value[6:8])
    2007              h = int(value[8:10])
    2008              m = int(value[10:12])
    2009              s = int(value[12:14])
    2010              return datetime(Y, M, D, h, m, s)
    2011
    2012          def stringify_date(date):
    2013              return date.strftime("%Y%m%d%H%M%S")
    2014
    2015          class DatetimeElement(objectify.ObjectifiedDataElement):
    2016              def pyval(self):
    2017                  return parse_date(self.text)
    2018              pyval = property(pyval)
    2019
    2020          datetime_type = objectify.PyType(
    2021              "datetime", parse_date, DatetimeElement, stringify_date)
    2022          datetime_type.xmlSchemaTypes = "dateTime"
    2023          datetime_type.register()
    2024
    2025          NAMESPACE = "http://foo.net/xmlns"
    2026          NAMESPACE_MAP = {'ns': NAMESPACE}
    2027
    2028          r = objectify.Element("{%s}root" % NAMESPACE, nsmap=NAMESPACE_MAP)
    2029          time = datetime.now()
    2030          r.date = time
    2031
    2032          self.assertTrue(isinstance(r.date, DatetimeElement))
    2033          self.assertTrue(isinstance(r.date.pyval, datetime))
    2034
    2035          self.assertEqual(r.date.pyval, parse_date(stringify_date(time)))
    2036          self.assertEqual(r.date.text, stringify_date(time))
    2037
    2038          r.date = objectify.E.date(time)
    2039
    2040          self.assertTrue(isinstance(r.date, DatetimeElement))
    2041          self.assertTrue(isinstance(r.date.pyval, datetime))
    2042
    2043          self.assertEqual(r.date.pyval, parse_date(stringify_date(time)))
    2044          self.assertEqual(r.date.text, stringify_date(time))
    2045
    2046          date = objectify.DataElement(time)
    2047
    2048          self.assertTrue(isinstance(date, DatetimeElement))
    2049          self.assertTrue(isinstance(date.pyval, datetime))
    2050
    2051          self.assertEqual(date.pyval, parse_date(stringify_date(time)))
    2052          self.assertEqual(date.text, stringify_date(time))
    2053
    2054 -    def test_object_path(self):
    2055          root = self.XML(xml_str)
    2056          path = objectify.ObjectPath( "root.c1.c2" )
    2057          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2058          self.assertEqual(root.c1.c2.text, path(root).text)
    2059
    2060 -    def test_object_path_list(self):
    2061          root = self.XML(xml_str)
    2062          path = objectify.ObjectPath( ['root', 'c1', 'c2'] )
    2063          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2064          self.assertEqual(root.c1.c2.text, path(root).text)
    2065
    2066 -    def test_object_path_fail(self):
    2067          root = self.XML(xml_str)
    2068          path = objectify.ObjectPath( "root.c1.c99" )
    2069          self.assertRaises(AttributeError, path, root)
    2070
    2071 -    def test_object_path_default_absolute(self):
    2072          root = self.XML(xml_str)
    2073          path = objectify.ObjectPath( "root.c1.c99" )
    2074          self.assertEqual(None, path(root, None))
    2075          path = objectify.ObjectPath( "root.c99.c2" )
    2076          self.assertEqual(None, path(root, None))
    2077          path = objectify.ObjectPath( "notroot.c99.c2" )
    2078          self.assertEqual(None, path(root, None))
    2079
    2080 -    def test_object_path_default_relative(self):
    2081          root = self.XML(xml_str)
    2082          path = objectify.ObjectPath( ".c1.c99" )
    2083          self.assertEqual(None, path(root, None))
    2084          path = objectify.ObjectPath( ".c99.c2" )
    2085          self.assertEqual(None, path(root, None))
    2086
    2087 -    def test_object_path_syntax(self):
    2088          root = self.XML(xml_str)
    2089          path = objectify.ObjectPath("root .    {objectified}c1.   c2")
    2090          self.assertEqual(root.c1.c2.text, path(root).text)
    2091
    2092          path = objectify.ObjectPath("   root.{objectified}  c1.c2  [ 0 ]   ")
    2093          self.assertEqual(root.c1.c2.text, path(root).text)
    2094
    2095 -    def test_object_path_fail_parse_empty(self):
    2096          self.assertRaises(ValueError, objectify.ObjectPath, "")
    2097
    2098 -    def test_object_path_fail_parse_empty_list(self):
    2099          self.assertRaises(ValueError, objectify.ObjectPath, [])
    2100
    2101 -    def test_object_path_hasattr(self):
    2102          root = self.XML(xml_str)
    2103          path = objectify.ObjectPath( "root" )
    2104          self.assertTrue(path.hasattr(root))
    2105          path = objectify.ObjectPath( "root.c1" )
    2106          self.assertTrue(path.hasattr(root))
    2107          path = objectify.ObjectPath( "root.c1.c2" )
    2108          self.assertTrue(path.hasattr(root))
    2109          path = objectify.ObjectPath( "root.c1.{otherNS}c2" )
    2110          self.assertTrue(path.hasattr(root))
    2111          path = objectify.ObjectPath( "root.c1.c2[1]" )
    2112          self.assertTrue(path.hasattr(root))
    2113          path = objectify.ObjectPath( "root.c1.c2[2]" )
    2114          self.assertTrue(path.hasattr(root))
    2115          path = objectify.ObjectPath( "root.c1.c2[3]" )
    2116          self.assertFalse(path.hasattr(root))
    2117          path = objectify.ObjectPath( "root.c1[1].c2" )
    2118          self.assertFalse(path.hasattr(root))
    2119
    2120 -    def test_object_path_dot(self):
    2121          root = self.XML(xml_str)
    2122          path = objectify.ObjectPath( "." )
    2123          self.assertEqual(root.c1.c2.text, path(root).c1.c2.text)
    2124
    2125 -    def test_object_path_dot_list(self):
    2126          root = self.XML(xml_str)
    2127          path = objectify.ObjectPath( [''] )
    2128          self.assertEqual(root.c1.c2.text, path(root).c1.c2.text)
    2129
    2130 -    def test_object_path_dot_root(self):
    2131          root = self.XML(xml_str)
    2132          path = objectify.ObjectPath( ".c1.c2" )
    2133          self.assertEqual(root.c1.c2.text, path(root).text)
    2134
    2135 -    def test_object_path_dot_root_list(self):
    2136          root = self.XML(xml_str)
    2137          path = objectify.ObjectPath( ['', 'c1', 'c2'] )
    2138          self.assertEqual(root.c1.c2.text, path(root).text)
    2139
    2140 -    def test_object_path_index(self):
    2141          root = self.XML(xml_str)
    2142          path = objectify.ObjectPath( "root.c1[0].c2[0]" )
    2143          self.assertEqual(root.c1.c2.text, path(root).text)
    2144
    2145          path = objectify.ObjectPath( "root.c1[0].c2" )
    2146          self.assertEqual(root.c1.c2.text, path(root).text)
    2147
    2148          path = objectify.ObjectPath( "root.c1[0].c2[1]" )
    2149          self.assertEqual(root.c1.c2[1].text, path(root).text)
    2150
    2151          path = objectify.ObjectPath( "root.c1.c2[2]" )
    2152          self.assertEqual(root.c1.c2[2].text, path(root).text)
    2153
    2154          path = objectify.ObjectPath( "root.c1.c2[-1]" )
    2155          self.assertEqual(root.c1.c2[-1].text, path(root).text)
    2156
    2157          path = objectify.ObjectPath( "root.c1.c2[-3]" )
    2158          self.assertEqual(root.c1.c2[-3].text, path(root).text)
    2159
    2160 -    def test_object_path_index_list(self):
    2161          root = self.XML(xml_str)
    2162          path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[0]'] )
    2163          self.assertEqual(root.c1.c2.text, path(root).text)
    2164
    2165          path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[2]'] )
    2166          self.assertEqual(root.c1.c2[2].text, path(root).text)
    2167
    2168          path = objectify.ObjectPath( ['root', 'c1', 'c2[2]'] )
    2169          self.assertEqual(root.c1.c2[2].text, path(root).text)
    2170
    2171          path = objectify.ObjectPath( ['root', 'c1', 'c2[-1]'] )
    2172          self.assertEqual(root.c1.c2[-1].text, path(root).text)
    2173
    2174          path = objectify.ObjectPath( ['root', 'c1', 'c2[-3]'] )
    2175          self.assertEqual(root.c1.c2[-3].text, path(root).text)
    2176
    2177 -    def test_object_path_index_fail_parse(self):
    2178          self.assertRaises(ValueError, objectify.ObjectPath,
    2179                            "root.c1[0].c2[-1-2]")
    2180          self.assertRaises(ValueError, objectify.ObjectPath,
    2181                            ['root', 'c1[0]', 'c2[-1-2]'])
    2182
    2183          self.assertRaises(ValueError, objectify.ObjectPath,
    2184                            "root[2].c1.c2")
    2185          self.assertRaises(ValueError, objectify.ObjectPath,
    2186                            ['root[2]', 'c1', 'c2'])
    2187
    2188          self.assertRaises(ValueError, objectify.ObjectPath,
    2189                            [])
    2190          self.assertRaises(ValueError, objectify.ObjectPath,
    2191                            ['', '', ''])
    2192
    2193 -    def test_object_path_index_fail_lookup(self):
    2194          root = self.XML(xml_str)
    2195          path = objectify.ObjectPath("root.c1[9999].c2")
    2196          self.assertRaises(AttributeError, path, root)
    2197
    2198          path = objectify.ObjectPath("root.c1[0].c2[9999]")
    2199          self.assertRaises(AttributeError, path, root)
    2200
    2201          path = objectify.ObjectPath(".c1[9999].c2[0]")
    2202          self.assertRaises(AttributeError, path, root)
    2203
    2204          path = objectify.ObjectPath("root.c1[-2].c2")
    2205          self.assertRaises(AttributeError, path, root)
    2206
    2207          path = objectify.ObjectPath("root.c1[0].c2[-4]")
    2208          self.assertRaises(AttributeError, path, root)
    2209
    2210 -    def test_object_path_ns(self):
    2211          root = self.XML(xml_str)
    2212          path = objectify.ObjectPath( "{objectified}root.c1.c2" )
    2213          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2214          path = objectify.ObjectPath( "{objectified}root.{objectified}c1.c2" )
    2215          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2216          path = objectify.ObjectPath( "root.{objectified}c1.{objectified}c2" )
    2217          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2218          path = objectify.ObjectPath( "root.c1.{objectified}c2" )
    2219          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2220          path = objectify.ObjectPath( "root.c1.{otherNS}c2" )
    2221          self.assertEqual(getattr(root.c1, '{otherNS}c2').text,
    2222                            path.find(root).text)
    2223
    2224 -    def test_object_path_ns_list(self):
    2225          root = self.XML(xml_str)
    2226          path = objectify.ObjectPath( ['{objectified}root', 'c1', 'c2'] )
    2227          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2228          path = objectify.ObjectPath( ['{objectified}root', '{objectified}c1', 'c2'] )
    2229          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2230          path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2'] )
    2231          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2232          path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2[2]'] )
    2233          self.assertEqual(root.c1.c2[2].text, path.find(root).text)
    2234          path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2'] )
    2235          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2236          path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2[2]'] )
    2237          self.assertEqual(root.c1.c2[2].text, path.find(root).text)
    2238          path = objectify.ObjectPath( ['root', 'c1', '{otherNS}c2'] )
    2239          self.assertEqual(getattr(root.c1, '{otherNS}c2').text,
    2240                            path.find(root).text)
    2241
    2242 -    def test_object_path_set(self):
    2243          root = self.XML(xml_str)
    2244          path = objectify.ObjectPath( "root.c1.c2" )
    2245          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2246          self.assertEqual("1", root.c1.c2[1].text)
    2247
    2248          new_value = "my new value"
    2249          path.setattr(root, new_value)
    2250
    2251          self.assertEqual(new_value, root.c1.c2.text)
    2252          self.assertEqual(new_value, path(root).text)
    2253          self.assertEqual("1", root.c1.c2[1].text)
    2254
    2255 -    def test_object_path_set_element(self):
    2256          root = self.XML(xml_str)
    2257          path = objectify.ObjectPath( "root.c1.c2" )
    2258          self.assertEqual(root.c1.c2.text, path.find(root).text)
    2259          self.assertEqual("1", root.c1.c2[1].text)
    2260
    2261          new_el = self.Element("{objectified}test")
    2262          etree.SubElement(new_el, "{objectified}sub", myattr="ATTR").a = "TEST"
    2263          path.setattr(root, new_el.sub)
    2264
    2265          self.assertEqual("ATTR", root.c1.c2.get("myattr"))
    2266          self.assertEqual("TEST", root.c1.c2.a.text)
    2267          self.assertEqual("TEST", path(root).a.text)
    2268          self.assertEqual("1", root.c1.c2[1].text)
    2269
    2270 -    def test_object_path_set_create(self):
    2271          root = self.XML(xml_str)
    2272          path = objectify.ObjectPath( "root.c1.c99" )
    2273          self.assertRaises(AttributeError, path.find, root)
    2274
    2275          new_value = "my new value"
    2276          path.setattr(root, new_value)
    2277
    2278          self.assertEqual(1, len(root.c1.c99))
    2279          self.assertEqual(new_value, root.c1.c99.text)
    2280          self.assertEqual(new_value, path(root).text)
    2281
    2282 -    def test_object_path_set_create_element(self):
    2283          root = self.XML(xml_str)
    2284          path = objectify.ObjectPath( "root.c1.c99" )
    2285          self.assertRaises(AttributeError, path.find, root)
    2286
    2287          new_el = self.Element("{objectified}test")
    2288          etree.SubElement(new_el, "{objectified}sub", myattr="ATTR").a = "TEST"
    2289          path.setattr(root, new_el.sub)
    2290
    2291          self.assertEqual(1, len(root.c1.c99))
    2292          self.assertEqual("ATTR", root.c1.c99.get("myattr"))
    2293          self.assertEqual("TEST", root.c1.c99.a.text)
    2294          self.assertEqual("TEST", path(root).a.text)
    2295
    2296 -    def test_object_path_set_create_list(self):
    2297          root = self.XML(xml_str)
    2298          path = objectify.ObjectPath( "root.c1.c99" )
    2299          self.assertRaises(AttributeError, path.find, root)
    2300
    2301          new_el = self.Element("{objectified}test")
    2302          new_el.a = ["TEST1", "TEST2"]
    2303          new_el.a[0].set("myattr", "ATTR1")
    2304          new_el.a[1].set("myattr", "ATTR2")
    2305
    2306          path.setattr(root, list(new_el.a))
    2307
    2308          self.assertEqual(2, len(root.c1.c99))
    2309          self.assertEqual("ATTR1", root.c1.c99[0].get("myattr"))
    2310          self.assertEqual("TEST1", root.c1.c99[0].text)
    2311          self.assertEqual("ATTR2", root.c1.c99[1].get("myattr"))
    2312          self.assertEqual("TEST2", root.c1.c99[1].text)
    2313          self.assertEqual("TEST1", path(root).text)
    2314
    2315 -    def test_object_path_addattr(self):
    2316          root = self.XML(xml_str)
    2317          path = objectify.ObjectPath( "root.c1.c2" )
    2318          self.assertEqual(3, len(root.c1.c2))
    2319          path.addattr(root, "test")
    2320          self.assertEqual(4, len(root.c1.c2))
    2321          self.assertEqual(["0", "1", "2", "test"],
    2322                            [el.text for el in root.c1.c2])
    2323
    2324 -    def test_object_path_addattr_element(self):
    2325          root = self.XML(xml_str)
    2326          path = objectify.ObjectPath( "root.c1.c2" )
    2327          self.assertEqual(3, len(root.c1.c2))
    2328
    2329          new_el = self.Element("{objectified}test")
    2330          etree.SubElement(new_el, "{objectified}sub").a = "TEST"
    2331
    2332          path.addattr(root, new_el.sub)
    2333          self.assertEqual(4, len(root.c1.c2))
    2334          self.assertEqual("TEST", root.c1.c2[3].a.text)
    2335          self.assertEqual(["0", "1", "2"],
    2336                            [el.text for el in root.c1.c2[:3]])
    2337
    2338 -    def test_object_path_addattr_create(self):
    2339          root = self.XML(xml_str)
    2340          path = objectify.ObjectPath( "root.c1.c99" )
    2341          self.assertRaises(AttributeError, path.find, root)
    2342
    2343          new_value = "my new value"
    2344          path.addattr(root, new_value)
    2345
    2346          self.assertEqual(1, len(root.c1.c99))
    2347          self.assertEqual(new_value, root.c1.c99.text)
    2348          self.assertEqual(new_value, path(root).text)
    2349
    2350 -    def test_object_path_addattr_create_element(self):
    2351          root = self.XML(xml_str)
    2352          path = objectify.ObjectPath( "root.c1.c99" )
    2353          self.assertRaises(AttributeError, path.find, root)
    2354
    2355          new_el = self.Element("{objectified}test")
    2356          etree.SubElement(new_el, "{objectified}sub", myattr="ATTR").a = "TEST"
    2357
    2358          path.addattr(root, new_el.sub)
    2359          self.assertEqual(1, len(root.c1.c99))
    2360          self.assertEqual("TEST", root.c1.c99.a.text)
    2361          self.assertEqual("TEST", path(root).a.text)
    2362          self.assertEqual("ATTR", root.c1.c99.get("myattr"))
    2363
    2364 -    def test_object_path_addattr_create_list(self):
    2365          root = self.XML(xml_str)
    2366          path = objectify.ObjectPath( "root.c1.c99" )
    2367          self.assertRaises(AttributeError, path.find, root)
    2368
    2369          new_el = self.Element("{objectified}test")
    2370          new_el.a = ["TEST1", "TEST2"]
    2371
    2372          self.assertEqual(2, len(new_el.a))
    2373
    2374          path.addattr(root, list(new_el.a))
    2375          self.assertEqual(2, len(root.c1.c99))
    2376          self.assertEqual("TEST1", root.c1.c99.text)
    2377          self.assertEqual("TEST2", path(root)[1].text)
    2378
    2379 -    def test_descendant_paths(self):
    2380          root = self.XML(xml_str)
    2381          self.assertEqual(
    2382              ['{objectified}root', '{objectified}root.c1',
    2383               '{objectified}root.c1.c2',
    2384               '{objectified}root.c1.c2[1]', '{objectified}root.c1.c2[2]',
    2385               '{objectified}root.c1.{otherNS}c2', '{objectified}root.c1.{}c2'],
    2386              root.descendantpaths())
    2387
    2388 -    def test_descendant_paths_child(self):
    2389          root = self.XML(xml_str)
    2390          self.assertEqual(
    2391              ['{objectified}c1', '{objectified}c1.c2',
    2392               '{objectified}c1.c2[1]', '{objectified}c1.c2[2]',
    2393               '{objectified}c1.{otherNS}c2', '{objectified}c1.{}c2'],
    2394              root.c1.descendantpaths())
    2395
    2396 -    def test_descendant_paths_prefix(self):
    2397          root = self.XML(xml_str)
    2398          self.assertEqual(
    2399              ['root.{objectified}c1', 'root.{objectified}c1.c2',
    2400               'root.{objectified}c1.c2[1]', 'root.{objectified}c1.c2[2]',
    2401               'root.{objectified}c1.{otherNS}c2',
    2402               'root.{objectified}c1.{}c2'],
    2403              root.c1.descendantpaths('root'))
    2404
    2405 -    def test_pickle(self):
    2406          import pickle
    2407
    2408          root = self.XML(xml_str)
    2409          out = BytesIO()
    2410          pickle.dump(root, out)
    2411
    2412          new_root = pickle.loads(out.getvalue())
    2413          self.assertEqual(
    2414              etree.tostring(new_root),
    2415              etree.tostring(root))
    2416
    2417 -    def test_pickle_elementtree(self):
    2418          import pickle
    2419
    2420          tree = etree.ElementTree(self.XML(xml_str + "<?my pi?>"))
    2421          out = BytesIO()
    2422          pickle.dump(tree, out)
    2423
    2424          new_tree = pickle.loads(out.getvalue())
    2425          self.assertTrue(isinstance(new_tree, etree._ElementTree))
    2426          self.assertEqual(
    2427              etree.tostring(new_tree),
    2428              etree.tostring(tree))
    2429
    2430 -    def test_pickle_intelement(self):
    2431          self._test_pickle('<x>42</x>')
    2432          self._test_pickle(objectify.DataElement(42))
    2433
    2434 -    def test_pickle_floattelement(self):
    2435          self._test_pickle('<x>42.0</x>')
    2436          self._test_pickle(objectify.DataElement(42.0))
    2437
    2438 -    def test_pickle_strelement(self):
    2439          self._test_pickle('<x>Pickle me!</x>')
    2440          self._test_pickle(objectify.DataElement('Pickle me!'))
    2441
    2442 -    def test_pickle_boolelement(self):
    2443          self._test_pickle('<x>true</x>')
    2444          self._test_pickle('<x>false</x>')
    2445          self._test_pickle(objectify.DataElement(True))
    2446          self._test_pickle(objectify.DataElement(False))
    2447
    2448 -    def test_pickle_noneelement(self):
    2449          self._test_pickle('''
    2450  <x xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>''')
    2451          self._test_pickle(objectify.DataElement(None))
    2452
    2453 -    def _test_pickle(self, stringOrElt):
    2454          import pickle
    2455          if isinstance(stringOrElt, (etree._Element, etree._ElementTree)):
    2456              elt = stringOrElt
    2457          else:
    2458              elt = self.XML(stringOrElt)
    2459          out = BytesIO()
    2460          pickle.dump(elt, out)
    2461
    2462          new_elt = pickle.loads(out.getvalue())
    2463          self.assertEqual(
    2464              etree.tostring(new_elt),
    2465              etree.tostring(elt))
    2466
    2467      # E-Factory tests, need to use sub-elements as root element is always
    2468      # type-looked-up as ObjectifiedElement (no annotations)
    2469 -    def test_efactory_int(self):
    2470          E = objectify.E
    2471          root = E.root(E.val(23))
    2472          self.assertTrue(isinstance(root.val, objectify.IntElement))
    2473
    2474 -    def test_efactory_float(self):
    2475          E = objectify.E
    2476          root = E.root(E.val(233.23))
    2477          self.assertTrue(isinstance(root.val, objectify.FloatElement))
    2478
    2479 -    def test_efactory_str(self):
    2480          E = objectify.E
    2481          root = E.root(E.val("what?"))
    2482          self.assertTrue(isinstance(root.val, objectify.StringElement))
    2483
    2484 -    def test_efactory_unicode(self):
    2485          E = objectify.E
    2486          root = E.root(E.val(_str("blöödy häll", encoding="ISO-8859-1")))
    2487          self.assertTrue(isinstance(root.val, objectify.StringElement))
    2488
    2489 -    def test_efactory_bool(self):
    2490          E = objectify.E
    2491          root = E.root(E.val(True))
    2492          self.assertTrue(isinstance(root.val, objectify.BoolElement))
    2493
    2494 -    def test_efactory_none(self):
    2495          E = objectify.E
    2496          root = E.root(E.val(None))
    2497          self.assertTrue(isinstance(root.val, objectify.NoneElement))
    2498
    2499 -    def test_efactory_value_concatenation(self):
    2500          E = objectify.E
    2501          root = E.root(E.val(1, "foo", 2.0, "bar ", True, None))
    2502          self.assertTrue(isinstance(root.val, objectify.StringElement))
    2503
    2504 -    def test_efactory_attrib(self):
    2505          E = objectify.E
    2506          root = E.root(foo="bar")
    2507          self.assertEqual(root.get("foo"), "bar")
    2508
    2509 -    def test_efactory_nested(self):
    2510          E = objectify.E
    2511          DataElement = objectify.DataElement
    2512          root = E.root("text", E.sub(E.subsub()), "tail", DataElement(1),
    2513                        DataElement(2.0))
    2514          self.assertTrue(isinstance(root, objectify.ObjectifiedElement))
    2515          self.assertEqual(root.text, "text")
    2516          self.assertTrue(isinstance(root.sub, objectify.ObjectifiedElement))
    2517          self.assertEqual(root.sub.tail, "tail")
    2518          self.assertTrue(isinstance(root.sub.subsub, objectify.StringElement))
    2519          self.assertEqual(len(root.value), 2)
    2520          self.assertTrue(isinstance(root.value[0], objectify.IntElement))
    2521          self.assertTrue(isinstance(root.value[1], objectify.FloatElement))
    2522
    2523 -    def test_efactory_subtype(self):
    2524          class Attribute(objectify.ObjectifiedDataElement):
    2525              def __init__(self):
    2526                  objectify.ObjectifiedDataElement.__init__(self)
    2527                  self.set("datatype", "TYPE")
    2528                  self.set("range", "0.,1.")
    2529
    2530          attr = Attribute()
    2531          self.assertEqual(attr.text, None)
    2532          self.assertEqual(attr.get("datatype"), "TYPE")
    2533          self.assertEqual(attr.get("range"), "0.,1.")
    2534
    2535 -    def test_XML_base_url_docinfo(self):
    2536          root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2537          docinfo = root.getroottree().docinfo
    2538          self.assertEqual(docinfo.URL, "http://no/such/url")
    2539
    2540 -    def test_XML_set_base_url_docinfo(self):
    2541          root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2542          docinfo = root.getroottree().docinfo
    2543          self.assertEqual(docinfo.URL, "http://no/such/url")
    2544          docinfo.URL = "https://secret/url"
    2545          self.assertEqual(docinfo.URL, "https://secret/url")
    2546
    2547 -    def test_parse_stringio_base_url(self):
    2548          tree = objectify.parse(BytesIO("<root/>"), base_url="http://no/such/url")
    2549          docinfo = tree.docinfo
    2550          self.assertEqual(docinfo.URL, "http://no/such/url")
    2551
    2552 -    def test_parse_base_url_docinfo(self):
    2553          tree = objectify.parse(fileInTestDir('include/test_xinclude.xml'),
    2554                                 base_url="http://no/such/url")
    2555          docinfo = tree.docinfo
    2556          self.assertEqual(docinfo.URL, "http://no/such/url")
    2557
    2558 -    def test_xml_base(self):
    2559          root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2560          self.assertEqual(root.base, "http://no/such/url")
    2561          self.assertEqual(
    2562              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2563          root.base = "https://secret/url"
    2564          self.assertEqual(root.base, "https://secret/url")
    2565          self.assertEqual(
    2566              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2567              "https://secret/url")
    2568
    2569 -    def test_xml_base_attribute(self):
    2570          root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2571          self.assertEqual(root.base, "http://no/such/url")
    2572          self.assertEqual(
    2573              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2574          root.set('{http://www.w3.org/XML/1998/namespace}base',
    2575                   "https://secret/url")
    2576          self.assertEqual(root.base, "https://secret/url")
    2577          self.assertEqual(
    2578              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2579              "https://secret/url")
    2580
    2581 -    def test_standard_lookup(self):
    2582          XML = self.XML
    2583
    2584          xml = _bytes('''\
    2585          <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    2586            <i>5</i>
    2587            <i>-5</i>
    2588            <l>4294967296</l>
    2589            <l>-4294967296</l>
    2590            <f>1.1</f>
    2591            <b>true</b>
    2592            <b>false</b>
    2593            <s>Strange things happen, where strings collide</s>
    2594            <s>True</s>
    2595            <s>False</s>
    2596            <s>t</s>
    2597            <s>f</s>
    2598            <s></s>
    2599            <s>None</s>
    2600            <n xsi:nil="true" />
    2601          </root>
    2602          ''')
    2603          root = XML(xml)
    2604
    2605          for i in root.i:
    2606              self.assertTrue(isinstance(i, objectify.IntElement))
    2607          for l in root.l:
    2608              self.assertTrue(isinstance(l, objectify.IntElement))
    2609          for f in root.f:
    2610              self.assertTrue(isinstance(f, objectify.FloatElement))
    2611          for b in root.b:
    2612              self.assertTrue(isinstance(b, objectify.BoolElement))
    2613          self.assertEqual(True,  root.b[0])
    2614          self.assertEqual(False, root.b[1])
    2615          for s in root.s:
    2616              self.assertTrue(isinstance(s, objectify.StringElement))
    2617          self.assertTrue(isinstance(root.n, objectify.NoneElement))
    2618          self.assertEqual(None, root.n)
    2619
    2620 -def test_suite():
    2621      suite = unittest.TestSuite()
    2622      suite.addTests([unittest.makeSuite(ObjectifyTestCase)])
    2623      suite.addTests(doctest.DocTestSuite(objectify))
    2624      suite.addTests([make_doctest('../../../doc/objectify.txt')])
    2625      return suite
    2626
    2627  if __name__ == '__main__':
    2628      print('to test use test.py %s' % __file__)
    2629