1
2
3 """
4 Tests specific to the lxml.objectify API
5 """
6
7
8 import unittest, operator
9
10 from common_imports import etree, StringIO, HelperTestCase, fileInTestDir
11 from common_imports import SillyFileLike, canonicalize, doctest
12 from common_imports import itemgetter
13
14 from lxml import objectify
15
16 PYTYPE_NAMESPACE = "http://codespeak.net/lxml/objectify/pytype"
17 XML_SCHEMA_NS = "http://www.w3.org/2001/XMLSchema"
18 XML_SCHEMA_INSTANCE_NS = "http://www.w3.org/2001/XMLSchema-instance"
19 XML_SCHEMA_INSTANCE_TYPE_ATTR = "{%s}type" % XML_SCHEMA_INSTANCE_NS
20 XML_SCHEMA_NIL_ATTR = "{%s}nil" % XML_SCHEMA_INSTANCE_NS
21 DEFAULT_NSMAP = { "py" : PYTYPE_NAMESPACE,
22 "xsi" : XML_SCHEMA_INSTANCE_NS,
23 "xsd" : XML_SCHEMA_NS}
24
25 objectclass2xsitype = {
26
27 objectify.IntElement: ("int", "short", "byte", "unsignedShort",
28 "unsignedByte",),
29 objectify.LongElement: ("integer", "nonPositiveInteger", "negativeInteger",
30 "long", "nonNegativeInteger", "unsignedLong",
31 "unsignedInt", "positiveInteger",),
32 objectify.FloatElement: ("float", "double"),
33 objectify.BoolElement: ("boolean",),
34 objectify.StringElement: ("string", "normalizedString", "token", "language",
35 "Name", "NCName", "ID", "IDREF", "ENTITY",
36 "NMTOKEN", ),
37
38 }
39
40 xsitype2objclass = dict(( (v, k) for k in objectclass2xsitype
41 for v in objectclass2xsitype[k] ))
42
43 xml_str = '''\
44 <obj:root xmlns:obj="objectified" xmlns:other="otherNS">
45 <obj:c1 a1="A1" a2="A2" other:a3="A3">
46 <obj:c2>0</obj:c2>
47 <obj:c2>1</obj:c2>
48 <obj:c2>2</obj:c2>
49 <other:c2>3</other:c2>
50 <c2>3</c2>
51 </obj:c1>
52 </obj:root>'''
53
55 """Test cases for lxml.objectify
56 """
57 etree = etree
58
61
72
76
80
85
92
94 nsmap = {"my": "someNS",
95 "myother": "someOtherNS",
96 "myxsd": XML_SCHEMA_NS}
97 elt = objectify.Element("test", nsmap=nsmap)
98 self.assert_(PYTYPE_NAMESPACE in elt.nsmap.values())
99 for prefix, ns in nsmap.items():
100 self.assert_(prefix in elt.nsmap)
101 self.assertEquals(nsmap[prefix], elt.nsmap[prefix])
102
107
113
121
123 root = objectify.Element("root")
124 nsmap = {"my": "someNS",
125 "myother": "someOtherNS",
126 "myxsd": XML_SCHEMA_NS,}
127 root.sub = objectify.Element("test", nsmap=nsmap)
128 expected = nsmap.copy()
129 del expected["myxsd"]
130 expected.update(DEFAULT_NSMAP)
131 self.assertEquals(root.sub.nsmap, expected)
132
136
141
148
150 nsmap = {"my": "someNS",
151 "myother": "someOtherNS",
152 "myxsd": XML_SCHEMA_NS,}
153 value = objectify.DataElement("test", nsmap=nsmap)
154 self.assert_(PYTYPE_NAMESPACE in value.nsmap.values())
155 for prefix, ns in nsmap.items():
156 self.assert_(prefix in value.nsmap)
157 self.assertEquals(nsmap[prefix], value.nsmap[prefix])
158
163
169
177
179 root = objectify.Element("root")
180 nsmap = {"my": "someNS",
181 "myother": "someOtherNS",
182 "myxsd": XML_SCHEMA_NS}
183 root.value = objectify.DataElement("test", nsmap=nsmap)
184 expected = nsmap.copy()
185 del expected["myxsd"]
186 expected.update(DEFAULT_NSMAP)
187 self.assertEquals(root.value.nsmap, expected)
188
190
191 value = objectify.DataElement(23, _pytype="str", _xsi="foobar",
192 attrib={"gnu": "muh", "cat": "meeow",
193 "dog": "wuff"},
194 bird="tchilp", dog="grrr")
195 self.assertEquals(value.get("gnu"), "muh")
196 self.assertEquals(value.get("cat"), "meeow")
197 self.assertEquals(value.get("dog"), "grrr")
198 self.assertEquals(value.get("bird"), "tchilp")
199
201
202
203 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
204 attrib={"gnu": "muh", "cat": "meeow",
205 "dog": "wuff"},
206 bird="tchilp", dog="grrr")
207 value = objectify.DataElement(arg)
208 self.assert_(isinstance(value, objectify.StringElement))
209 for attr in arg.attrib:
210 self.assertEquals(value.get(attr), arg.get(attr))
211
213
214
215 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
216 attrib={"gnu": "muh", "cat": "meeow",
217 "dog": "wuff"},
218 bird="tchilp", dog="grrr")
219 value = objectify.DataElement(arg, _pytype="int")
220 self.assert_(isinstance(value, objectify.IntElement))
221 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
222 for attr in arg.attrib:
223 if not attr == objectify.PYTYPE_ATTRIBUTE:
224 self.assertEquals(value.get(attr), arg.get(attr))
225
227
228
229 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
230 attrib={"gnu": "muh", "cat": "meeow",
231 "dog": "wuff"},
232 bird="tchilp", dog="grrr")
233 value = objectify.DataElement(arg, _xsi="xsd:int")
234 self.assert_(isinstance(value, objectify.IntElement))
235 self.assertEquals(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
236 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
237 for attr in arg.attrib:
238 if not attr in [objectify.PYTYPE_ATTRIBUTE,
239 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
240 self.assertEquals(value.get(attr), arg.get(attr))
241
243
244
245 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
246 attrib={"gnu": "muh", "cat": "meeow",
247 "dog": "wuff"},
248 bird="tchilp", dog="grrr")
249 value = objectify.DataElement(arg, _pytype="int", _xsi="xsd:int")
250 self.assert_(isinstance(value, objectify.IntElement))
251 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
252 self.assertEquals(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
253 for attr in arg.attrib:
254 if not attr in [objectify.PYTYPE_ATTRIBUTE,
255 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
256 self.assertEquals(value.get(attr), arg.get(attr))
257
261
265
270
275
277 root = self.Element("test")
278 self.assert_(isinstance(root, objectify.ObjectifiedElement))
279
281 root = self.Element("test")
282 self.assertEquals('', str(root))
283
285 root = self.XML(xml_str)
286 self.assertEquals("0", root.c1.c2.text)
287
289 root = self.XML(xml_str)
290 self.assertEquals(1, root.countchildren())
291 self.assertEquals(5, root.c1.countchildren())
292
294 root = self.XML(xml_str)
295 self.assertEquals("0", getattr(root.c1, "{objectified}c2").text)
296 self.assertEquals("3", getattr(root.c1, "{otherNS}c2").text)
297
299 root = self.XML(xml_str)
300 self.assertRaises(AttributeError, getattr, root.c1, "NOT_THERE")
301 self.assertRaises(AttributeError, getattr, root.c1, "{unknownNS}c2")
302
304 root = self.XML(xml_str)
305 self.assertEquals(1, len(root.c1))
306 root.addattr("c1", "test")
307 self.assertEquals(2, len(root.c1))
308 self.assertEquals("test", root.c1[1].text)
309
311 root = self.XML(xml_str)
312 self.assertEquals(1, len(root.c1))
313
314 new_el = self.Element("test", myattr="5")
315 root.addattr("c1", new_el)
316 self.assertEquals(2, len(root.c1))
317 self.assertEquals(None, root.c1[0].get("myattr"))
318 self.assertEquals("5", root.c1[1].get("myattr"))
319
321 root = self.XML(xml_str)
322 self.assertEquals(1, len(root.c1))
323
324 new_el = self.Element("test")
325 self.etree.SubElement(new_el, "a", myattr="A")
326 self.etree.SubElement(new_el, "a", myattr="B")
327
328 root.addattr("c1", list(new_el.a))
329 self.assertEquals(3, len(root.c1))
330 self.assertEquals(None, root.c1[0].get("myattr"))
331 self.assertEquals("A", root.c1[1].get("myattr"))
332 self.assertEquals("B", root.c1[2].get("myattr"))
333
335 root = self.XML(xml_str)
336 self.assertEquals(3, len(root.c1.c2))
337 root.c1.addattr("c2", 3)
338 self.assertEquals(4, len(root.c1.c2))
339 self.assertEquals("3", root.c1.c2[3].text)
340
342 root = self.XML(xml_str)
343 self.assertEquals("0", root.c1.c2[0].text)
344 self.assertEquals("1", root.c1.c2[1].text)
345 self.assertEquals("2", root.c1.c2[2].text)
346 self.assertRaises(IndexError, itemgetter(3), root.c1.c2)
347
349 root = self.XML(xml_str)
350 self.assertEquals("0", root.c1.c2[0].text)
351 self.assertEquals("0", root.c1.c2[-3].text)
352 self.assertEquals("1", root.c1.c2[-2].text)
353 self.assertEquals("2", root.c1.c2[-1].text)
354 self.assertRaises(IndexError, itemgetter(-4), root.c1.c2)
355
357 root = self.XML(xml_str)
358 self.assertEquals(1, len(root))
359 self.assertEquals(1, len(root.c1))
360 self.assertEquals(3, len(root.c1.c2))
361
363 root = self.XML(xml_str)
364 self.assertEquals([root],
365 list(iter(root)))
366 self.assertEquals([root.c1],
367 list(iter(root.c1)))
368 self.assertEquals([root.c1.c2[0], root.c1.c2[1], root.c1.c2[2]],
369 list(iter((root.c1.c2))))
370
372 root = self.XML(xml_str)
373 self.assert_(isinstance(root.c1.c2, objectify.ObjectifiedElement))
374 self.assertFalse(isinstance(getattr(root.c1, "{otherNS}c2"),
375 objectify.ObjectifiedElement))
376
378 root = self.XML(xml_str)
379 dir_c1 = dir(objectify.ObjectifiedElement) + ['c1']
380 dir_c1.sort()
381 dir_c2 = dir(objectify.ObjectifiedElement) + ['c2']
382 dir_c2.sort()
383
384 self.assertEquals(dir_c1, dir(root))
385 self.assertEquals(dir_c2, dir(root.c1))
386
388 root = self.XML(xml_str)
389 self.assertEquals({'c1' : root.c1}, vars(root))
390 self.assertEquals({'c2' : root.c1.c2}, vars(root.c1))
391
393 root = self.XML(xml_str)
394 self.assertRaises(TypeError, setattr, root.c1.c2, 'text', "test")
395 self.assertRaises(TypeError, setattr, root.c1.c2, 'pyval', "test")
396
398 Element = self.Element
399 SubElement = self.etree.SubElement
400 root = Element("root")
401 root.c = ["c1", "c2"]
402
403 c1 = root.c[0]
404 c2 = root.c[1]
405
406 self.assertEquals([c1,c2], list(root.c))
407 self.assertEquals(["c1", "c2"],
408 [ c.text for c in root.c ])
409
410 root2 = Element("root2")
411 root2.el = [ "test", "test" ]
412 self.assertEquals(["test", "test"],
413 [ el.text for el in root2.el ])
414
415 root.c = [ root2.el, root2.el ]
416 self.assertEquals(["test", "test"],
417 [ c.text for c in root.c ])
418 self.assertEquals(["test", "test"],
419 [ el.text for el in root2.el ])
420
421 root.c[:] = [ c1, c2, c2, c1 ]
422 self.assertEquals(["c1", "c2", "c2", "c1"],
423 [ c.text for c in root.c ])
424
433
442
444
445 Element = self.Element
446 SubElement = self.etree.SubElement
447 root = Element("root")
448
449 root["text"] = "TEST"
450 self.assertEquals(["TEST"],
451 [ c.text for c in root["text"] ])
452
453 root["tail"] = "TEST"
454 self.assertEquals(["TEST"],
455 [ c.text for c in root["tail"] ])
456
457 root["pyval"] = "TEST"
458 self.assertEquals(["TEST"],
459 [ c.text for c in root["pyval"] ])
460
461 root["tag"] = "TEST"
462 self.assertEquals(["TEST"],
463 [ c.text for c in root["tag"] ])
464
466 XML = self.XML
467 root = XML('<a><b><c/></b><b/><c><b/></c></a>')
468 self.assertEquals(1, len(root.findall("c")))
469 self.assertEquals(2, len(root.findall(".//c")))
470 self.assertEquals(3, len(root.findall(".//b")))
471 self.assert_(root.findall(".//b")[1] is root.getchildren()[1])
472
474 XML = self.XML
475 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')
476 self.assertEquals(2, len(root.findall(".//{X}b")))
477 self.assertEquals(3, len(root.findall(".//b")))
478 self.assertEquals(2, len(root.findall("b")))
479
481 root = self.Element('root')
482 root.a = 5
483 root.b = 6
484 self.assert_(isinstance(root, objectify.ObjectifiedElement))
485 self.assert_(isinstance(root.a, objectify.IntElement))
486 self.assert_(isinstance(root.b, objectify.IntElement))
487
501
507
509 Element = self.Element
510 SubElement = self.etree.SubElement
511 root = Element("{objectified}root")
512 root.bool = 'true'
513 self.assert_(isinstance(root.bool, objectify.BoolElement))
514 self.assertEquals(root.bool, True)
515
516 root.bool = 'false'
517 self.assert_(isinstance(root.bool, objectify.BoolElement))
518 self.assertEquals(root.bool, False)
519
528
535
537 Element = self.Element
538 SubElement = self.etree.SubElement
539 root = Element("{objectified}root")
540 root.none = "test"
541
542 self.assertEquals("test" * 5, root.none * 5)
543 self.assertEquals(5 * "test", 5 * root.none)
544
545 self.assertRaises(TypeError, operator.mul, root.none, "honk")
546 self.assertRaises(TypeError, operator.mul, "honk", root.none)
547
549 Element = self.Element
550 SubElement = self.etree.SubElement
551 root = Element("{objectified}root")
552 root.none = "test"
553
554 s = "toast"
555 self.assertEquals("test" + s, root.none + s)
556 self.assertEquals(s + "test", s + root.none)
557
562
569
574
581
586
592
598
604
606 XML = self.XML
607 root = XML('''\
608 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
609 <b xsi:type="boolean">true</b>
610 <b xsi:type="boolean">false</b>
611 <b xsi:type="boolean">1</b>
612 <b xsi:type="boolean">0</b>
613
614 <f xsi:type="float">5</f>
615 <f xsi:type="double">5</f>
616
617 <s xsi:type="string">5</s>
618 <s xsi:type="normalizedString">5</s>
619 <s xsi:type="token">5</s>
620 <s xsi:type="language">5</s>
621 <s xsi:type="Name">5</s>
622 <s xsi:type="NCName">5</s>
623 <s xsi:type="ID">5</s>
624 <s xsi:type="IDREF">5</s>
625 <s xsi:type="ENTITY">5</s>
626 <s xsi:type="NMTOKEN">5</s>
627
628 <l xsi:type="integer">5</l>
629 <l xsi:type="nonPositiveInteger">5</l>
630 <l xsi:type="negativeInteger">5</l>
631 <l xsi:type="long">5</l>
632 <l xsi:type="nonNegativeInteger">5</l>
633 <l xsi:type="unsignedLong">5</l>
634 <l xsi:type="unsignedInt">5</l>
635 <l xsi:type="positiveInteger">5</l>
636
637 <i xsi:type="int">5</i>
638 <i xsi:type="short">5</i>
639 <i xsi:type="byte">5</i>
640 <i xsi:type="unsignedShort">5</i>
641 <i xsi:type="unsignedByte">5</i>
642
643 <n xsi:nil="true"/>
644 </root>
645 ''')
646
647 for b in root.b:
648 self.assert_(isinstance(b, objectify.BoolElement))
649 self.assertEquals(True, root.b[0])
650 self.assertEquals(False, root.b[1])
651 self.assertEquals(True, root.b[2])
652 self.assertEquals(False, root.b[3])
653
654 for f in root.f:
655 self.assert_(isinstance(f, objectify.FloatElement))
656 self.assertEquals(5, f)
657
658 for s in root.s:
659 self.assert_(isinstance(s, objectify.StringElement))
660 self.assertEquals("5", s)
661
662 for l in root.l:
663 self.assert_(isinstance(l, objectify.LongElement))
664 self.assertEquals(5L, l)
665
666 for i in root.i:
667 self.assert_(isinstance(i, objectify.IntElement))
668 self.assertEquals(5, i)
669
670 self.assert_(isinstance(root.n, objectify.NoneElement))
671 self.assertEquals(None, root.n)
672
674 XML = self.XML
675 root = XML('''\
676 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
677 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
678 <b xsi:type="xsd:boolean">true</b>
679 <b xsi:type="xsd:boolean">false</b>
680 <b xsi:type="xsd:boolean">1</b>
681 <b xsi:type="xsd:boolean">0</b>
682
683 <f xsi:type="xsd:float">5</f>
684 <f xsi:type="xsd:double">5</f>
685
686 <s xsi:type="xsd:string">5</s>
687 <s xsi:type="xsd:normalizedString">5</s>
688 <s xsi:type="xsd:token">5</s>
689 <s xsi:type="xsd:language">5</s>
690 <s xsi:type="xsd:Name">5</s>
691 <s xsi:type="xsd:NCName">5</s>
692 <s xsi:type="xsd:ID">5</s>
693 <s xsi:type="xsd:IDREF">5</s>
694 <s xsi:type="xsd:ENTITY">5</s>
695 <s xsi:type="xsd:NMTOKEN">5</s>
696
697 <l xsi:type="xsd:integer">5</l>
698 <l xsi:type="xsd:nonPositiveInteger">5</l>
699 <l xsi:type="xsd:negativeInteger">5</l>
700 <l xsi:type="xsd:long">5</l>
701 <l xsi:type="xsd:nonNegativeInteger">5</l>
702 <l xsi:type="xsd:unsignedLong">5</l>
703 <l xsi:type="xsd:unsignedInt">5</l>
704 <l xsi:type="xsd:positiveInteger">5</l>
705
706 <i xsi:type="xsd:int">5</i>
707 <i xsi:type="xsd:short">5</i>
708 <i xsi:type="xsd:byte">5</i>
709 <i xsi:type="xsd:unsignedShort">5</i>
710 <i xsi:type="xsd:unsignedByte">5</i>
711
712 <n xsi:nil="true"/>
713 </root>
714 ''')
715
716 for b in root.b:
717 self.assert_(isinstance(b, objectify.BoolElement))
718 self.assertEquals(True, root.b[0])
719 self.assertEquals(False, root.b[1])
720 self.assertEquals(True, root.b[2])
721 self.assertEquals(False, root.b[3])
722
723 for f in root.f:
724 self.assert_(isinstance(f, objectify.FloatElement))
725 self.assertEquals(5, f)
726
727 for s in root.s:
728 self.assert_(isinstance(s, objectify.StringElement))
729 self.assertEquals("5", s)
730
731 for l in root.l:
732 self.assert_(isinstance(l, objectify.LongElement))
733 self.assertEquals(5L, l)
734
735 for i in root.i:
736 self.assert_(isinstance(i, objectify.IntElement))
737 self.assertEquals(5, i)
738
739 self.assert_(isinstance(root.n, objectify.NoneElement))
740 self.assertEquals(None, root.n)
741
743 XML = self.XML
744 root = XML(u'<root><b>why</b><b>try</b></root>')
745 strs = [ str(s) for s in root.b ]
746 self.assertEquals(["why", "try"],
747 strs)
748
750 XML = self.XML
751 root = XML(u'<root><b>test</b><b>taste</b></root>')
752 self.assertFalse(root.b[0] < root.b[1])
753 self.assertFalse(root.b[0] <= root.b[1])
754 self.assertFalse(root.b[0] == root.b[1])
755
756 self.assert_(root.b[0] != root.b[1])
757 self.assert_(root.b[0] >= root.b[1])
758 self.assert_(root.b[0] > root.b[1])
759
760 self.assertEquals(root.b[0], "test")
761 self.assertEquals("test", root.b[0])
762 self.assert_(root.b[0] > 5)
763 self.assert_(5 < root.b[0])
764
765 root.b = "test"
766 self.assert_(root.b)
767 root.b = ""
768 self.assertFalse(root.b)
769
771 XML = self.XML
772 root = XML(u'<root><b>5</b><b>6</b></root>')
773 self.assert_(root.b[0] < root.b[1])
774 self.assert_(root.b[0] <= root.b[1])
775 self.assert_(root.b[0] != root.b[1])
776
777 self.assertFalse(root.b[0] == root.b[1])
778 self.assertFalse(root.b[0] >= root.b[1])
779 self.assertFalse(root.b[0] > root.b[1])
780
781 self.assertEquals(root.b[0], 5)
782 self.assertEquals(5, root.b[0])
783 self.assert_(root.b[0] < "5")
784 self.assert_("5" > root.b[0])
785
786 root.b = 5
787 self.assert_(root.b)
788 root.b = 0
789 self.assertFalse(root.b)
790
792 XML = self.XML
793 root = XML(u'<root><b>false</b><b>true</b></root>')
794 self.assert_(root.b[0] < root.b[1])
795 self.assert_(root.b[0] <= root.b[1])
796 self.assert_(root.b[0] != root.b[1])
797
798 self.assertFalse(root.b[0] == root.b[1])
799 self.assertFalse(root.b[0] >= root.b[1])
800 self.assertFalse(root.b[0] > root.b[1])
801
802 self.assertFalse(root.b[0])
803 self.assert_(root.b[1])
804
805 self.assertEquals(root.b[0], False)
806 self.assertEquals(False, root.b[0])
807 self.assert_(root.b[0] < 5)
808 self.assert_(5 > root.b[0])
809
810 root.b = True
811 self.assert_(root.b)
812 root.b = False
813 self.assertFalse(root.b)
814
816 XML = self.XML
817 root = XML(u'''\
818 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
819 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
820 <b>5</b>
821 <b>test</b>
822 <c>1.1</c>
823 <c>\uF8D2</c>
824 <x>true</x>
825 <n xsi:nil="true" />
826 <n></n>
827 <b xsi:type="double">5</b>
828 <b xsi:type="float">5</b>
829 <s xsi:type="string">23</s>
830 <s py:pytype="str">42</s>
831 <f py:pytype="float">300</f>
832 <l py:pytype="long">2</l>
833 </a>
834 ''')
835 objectify.annotate(root)
836
837 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
838 for c in root.iterchildren() ]
839 self.assertEquals("int", child_types[ 0])
840 self.assertEquals("str", child_types[ 1])
841 self.assertEquals("float", child_types[ 2])
842 self.assertEquals("str", child_types[ 3])
843 self.assertEquals("bool", child_types[ 4])
844 self.assertEquals("none", child_types[ 5])
845 self.assertEquals(None, child_types[ 6])
846 self.assertEquals("float", child_types[ 7])
847 self.assertEquals("float", child_types[ 8])
848 self.assertEquals("str", child_types[ 9])
849 self.assertEquals("int", child_types[10])
850 self.assertEquals("int", child_types[11])
851 self.assertEquals("int", child_types[12])
852
853 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
854
856 XML = self.XML
857 root = XML(u'''\
858 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
859 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
860 <b>5</b>
861 <b>test</b>
862 <c>1.1</c>
863 <c>\uF8D2</c>
864 <x>true</x>
865 <n xsi:nil="true" />
866 <n></n>
867 <b xsi:type="double">5</b>
868 <b xsi:type="float">5</b>
869 <s xsi:type="string">23</s>
870 <s py:pytype="str">42</s>
871 <f py:pytype="float">300</f>
872 <l py:pytype="long">2</l>
873 </a>
874 ''')
875 objectify.annotate(root, ignore_old=False)
876
877 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
878 for c in root.iterchildren() ]
879 self.assertEquals("int", child_types[ 0])
880 self.assertEquals("str", child_types[ 1])
881 self.assertEquals("float", child_types[ 2])
882 self.assertEquals("str", child_types[ 3])
883 self.assertEquals("bool", child_types[ 4])
884 self.assertEquals("none", child_types[ 5])
885 self.assertEquals(None, child_types[ 6])
886 self.assertEquals("float", child_types[ 7])
887 self.assertEquals("float", child_types[ 8])
888 self.assertEquals("str", child_types[ 9])
889 self.assertEquals("str", child_types[10])
890 self.assertEquals("float", child_types[11])
891 self.assertEquals("long", child_types[12])
892
893 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
894
896 XML = self.XML
897 root = XML(u'''\
898 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
899 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
900 <b>5</b>
901 <b>test</b>
902 <c>1.1</c>
903 <c>\uF8D2</c>
904 <x>true</x>
905 <n xsi:nil="true" />
906 <n></n>
907 <b xsi:type="double">5</b>
908 <b xsi:type="float">5</b>
909 <s xsi:type="string">23</s>
910 <s py:pytype="str">42</s>
911 <f py:pytype="float">300</f>
912 <l py:pytype="long">2</l>
913 </a>
914 ''')
915 objectify.deannotate(root)
916
917 for c in root.getiterator():
918 self.assertEquals(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
919 self.assertEquals(None, c.get(objectify.PYTYPE_ATTRIBUTE))
920
921 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
922
924 XML = self.XML
925 root = XML(u'''\
926 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
927 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
928 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
929 <b>5</b>
930 <b>test</b>
931 <c>1.1</c>
932 <c>\uF8D2</c>
933 <x>true</x>
934 <n xsi:nil="true" />
935 <n></n>
936 <b xsi:type="xsd:double">5</b>
937 <b xsi:type="xsd:float">5</b>
938 <s xsi:type="xsd:string">23</s>
939 <s py:pytype="str">42</s>
940 <f py:pytype="float">300</f>
941 <l py:pytype="long">2</l>
942 </a>
943 ''')
944 objectify.annotate(root)
945 objectify.deannotate(root, pytype=False)
946
947 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
948 for c in root.iterchildren() ]
949 self.assertEquals("int", child_types[ 0])
950 self.assertEquals("str", child_types[ 1])
951 self.assertEquals("float", child_types[ 2])
952 self.assertEquals("str", child_types[ 3])
953 self.assertEquals("bool", child_types[ 4])
954 self.assertEquals("none", child_types[ 5])
955 self.assertEquals(None, child_types[ 6])
956 self.assertEquals("float", child_types[ 7])
957 self.assertEquals("float", child_types[ 8])
958 self.assertEquals("str", child_types[ 9])
959 self.assertEquals("int", child_types[10])
960 self.assertEquals("int", child_types[11])
961 self.assertEquals("int", child_types[12])
962
963 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
964
965 for c in root.getiterator():
966 self.assertEquals(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
967
969 XML = self.XML
970 root = XML(u'''\
971 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
972 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
973 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
974 <b xsi:type="xsd:int">5</b>
975 <b xsi:type="xsd:string">test</b>
976 <c xsi:type="xsd:float">1.1</c>
977 <c xsi:type="xsd:string">\uF8D2</c>
978 <x xsi:type="xsd:boolean">true</x>
979 <n xsi:nil="true" />
980 <n></n>
981 <b xsi:type="xsd:double">5</b>
982 <b xsi:type="xsd:float">5</b>
983 <s xsi:type="xsd:string">23</s>
984 <s xsi:type="xsd:string">42</s>
985 <f xsi:type="xsd:float">300</f>
986 <l xsi:type="xsd:long">2</l>
987 </a>
988 ''')
989 objectify.annotate(root)
990 objectify.deannotate(root, xsi=False)
991
992 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
993 for c in root.iterchildren() ]
994 self.assertEquals("xsd:int", child_types[ 0])
995 self.assertEquals("xsd:string", child_types[ 1])
996 self.assertEquals("xsd:float", child_types[ 2])
997 self.assertEquals("xsd:string", child_types[ 3])
998 self.assertEquals("xsd:boolean", child_types[ 4])
999 self.assertEquals(None, child_types[ 5])
1000 self.assertEquals(None, child_types[ 6])
1001 self.assertEquals("xsd:double", child_types[ 7])
1002 self.assertEquals("xsd:float", child_types[ 8])
1003 self.assertEquals("xsd:string", child_types[ 9])
1004 self.assertEquals("xsd:string", child_types[10])
1005 self.assertEquals("xsd:float", child_types[11])
1006 self.assertEquals("xsd:long", child_types[12])
1007
1008 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1009
1010 for c in root.getiterator():
1011 self.assertEquals(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1012
1014 XML = self.XML
1015
1016 xml = u'''\
1017 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1018 <b>5</b>
1019 <b>test</b>
1020 <c>1.1</c>
1021 <c>\uF8D2</c>
1022 <x>true</x>
1023 <n xsi:nil="true" />
1024 <n></n>
1025 <b xsi:type="double">5</b>
1026 </a>
1027 '''
1028
1029 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1030 objectify.setPytypeAttributeTag("{TEST}test")
1031
1032 root = XML(xml)
1033 objectify.annotate(root)
1034
1035 attribs = root.xpath("//@py:%s" % pytype_name, {"py" : pytype_ns})
1036 self.assertEquals(0, len(attribs))
1037 attribs = root.xpath("//@py:test", {"py" : "TEST"})
1038 self.assertEquals(7, len(attribs))
1039
1040 objectify.setPytypeAttributeTag()
1041 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1042
1043 self.assertNotEqual("test", pytype_ns.lower())
1044 self.assertNotEqual("test", pytype_name.lower())
1045
1046 root = XML(xml)
1047 attribs = root.xpath("//@py:%s" % pytype_name, {"py" : pytype_ns})
1048 self.assertEquals(0, len(attribs))
1049
1050 objectify.annotate(root)
1051 attribs = root.xpath("//@py:%s" % pytype_name, {"py" : pytype_ns})
1052 self.assertEquals(7, len(attribs))
1053
1063
1064 def checkMyType(s):
1065 return True
1066
1067 pytype = objectify.PyType("mytype", checkMyType, NewType)
1068 pytype.register()
1069 self.assert_(pytype in objectify.getRegisteredTypes())
1070 pytype.unregister()
1071
1072 pytype.register(before = [objectify.getRegisteredTypes()[0].name])
1073 self.assertEquals(pytype, objectify.getRegisteredTypes()[0])
1074 pytype.unregister()
1075
1076 pytype.register(after = [objectify.getRegisteredTypes()[0].name])
1077 self.assertNotEqual(pytype, objectify.getRegisteredTypes()[0])
1078 pytype.unregister()
1079
1080 self.assertRaises(ValueError, pytype.register,
1081 before = [objectify.getRegisteredTypes()[0].name],
1082 after = [objectify.getRegisteredTypes()[1].name])
1083
1084 finally:
1085 for pytype in objectify.getRegisteredTypes():
1086 pytype.unregister()
1087 for pytype in orig_types:
1088 pytype.register()
1089
1091 root = self.XML(xml_str)
1092 path = objectify.ObjectPath( "root.c1.c2" )
1093 self.assertEquals(root.c1.c2.text, path.find(root).text)
1094 self.assertEquals(root.c1.c2.text, path(root).text)
1095
1097 root = self.XML(xml_str)
1098 path = objectify.ObjectPath( ['root', 'c1', 'c2'] )
1099 self.assertEquals(root.c1.c2.text, path.find(root).text)
1100 self.assertEquals(root.c1.c2.text, path(root).text)
1101
1103 root = self.XML(xml_str)
1104 path = objectify.ObjectPath( "root.c1.c99" )
1105 self.assertRaises(AttributeError, path, root)
1106 self.assertEquals(None, path(root, None))
1107
1109 root = self.XML(xml_str)
1110 path = objectify.ObjectPath("root . {objectified}c1. c2")
1111 self.assertEquals(root.c1.c2.text, path(root).text)
1112
1113 path = objectify.ObjectPath(" root.{objectified} c1.c2 [ 0 ] ")
1114 self.assertEquals(root.c1.c2.text, path(root).text)
1115
1117 root = self.XML(xml_str)
1118 path = objectify.ObjectPath( "root" )
1119 self.assert_(path.hasattr(root))
1120 path = objectify.ObjectPath( "root.c1" )
1121 self.assert_(path.hasattr(root))
1122 path = objectify.ObjectPath( "root.c1.c2" )
1123 self.assert_(path.hasattr(root))
1124 path = objectify.ObjectPath( "root.c1.{otherNS}c2" )
1125 self.assert_(path.hasattr(root))
1126 path = objectify.ObjectPath( "root.c1.c2[1]" )
1127 self.assert_(path.hasattr(root))
1128 path = objectify.ObjectPath( "root.c1.c2[2]" )
1129 self.assert_(path.hasattr(root))
1130 path = objectify.ObjectPath( "root.c1.c2[3]" )
1131 self.assertFalse(path.hasattr(root))
1132 path = objectify.ObjectPath( "root.c1[1].c2" )
1133 self.assertFalse(path.hasattr(root))
1134
1139
1144
1149
1151 root = self.XML(xml_str)
1152 path = objectify.ObjectPath( ['', 'c1', 'c2'] )
1153 self.assertEquals(root.c1.c2.text, path(root).text)
1154
1156 root = self.XML(xml_str)
1157 path = objectify.ObjectPath( "root.c1[0].c2[0]" )
1158 self.assertEquals(root.c1.c2.text, path(root).text)
1159
1160 path = objectify.ObjectPath( "root.c1[0].c2" )
1161 self.assertEquals(root.c1.c2.text, path(root).text)
1162
1163 path = objectify.ObjectPath( "root.c1[0].c2[1]" )
1164 self.assertEquals(root.c1.c2[1].text, path(root).text)
1165
1166 path = objectify.ObjectPath( "root.c1.c2[2]" )
1167 self.assertEquals(root.c1.c2[2].text, path(root).text)
1168
1169 path = objectify.ObjectPath( "root.c1.c2[-1]" )
1170 self.assertEquals(root.c1.c2[-1].text, path(root).text)
1171
1172 path = objectify.ObjectPath( "root.c1.c2[-3]" )
1173 self.assertEquals(root.c1.c2[-3].text, path(root).text)
1174
1176 root = self.XML(xml_str)
1177 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[0]'] )
1178 self.assertEquals(root.c1.c2.text, path(root).text)
1179
1180 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[2]'] )
1181 self.assertEquals(root.c1.c2[2].text, path(root).text)
1182
1183 path = objectify.ObjectPath( ['root', 'c1', 'c2[2]'] )
1184 self.assertEquals(root.c1.c2[2].text, path(root).text)
1185
1186 path = objectify.ObjectPath( ['root', 'c1', 'c2[-1]'] )
1187 self.assertEquals(root.c1.c2[-1].text, path(root).text)
1188
1189 path = objectify.ObjectPath( ['root', 'c1', 'c2[-3]'] )
1190 self.assertEquals(root.c1.c2[-3].text, path(root).text)
1191
1193 self.assertRaises(ValueError, objectify.ObjectPath,
1194 "root.c1[0].c2[-1-2]")
1195 self.assertRaises(ValueError, objectify.ObjectPath,
1196 ['root', 'c1[0]', 'c2[-1-2]'])
1197
1198 self.assertRaises(ValueError, objectify.ObjectPath,
1199 "root[2].c1.c2")
1200 self.assertRaises(ValueError, objectify.ObjectPath,
1201 ['root[2]', 'c1', 'c2'])
1202
1203 self.assertRaises(ValueError, objectify.ObjectPath,
1204 [])
1205 self.assertRaises(ValueError, objectify.ObjectPath,
1206 ['', '', ''])
1207
1209 root = self.XML(xml_str)
1210 path = objectify.ObjectPath("root.c1[9999].c2")
1211 self.assertRaises(AttributeError, path, root)
1212
1213 path = objectify.ObjectPath("root.c1[0].c2[9999]")
1214 self.assertRaises(AttributeError, path, root)
1215
1216 path = objectify.ObjectPath(".c1[9999].c2[0]")
1217 self.assertRaises(AttributeError, path, root)
1218
1219 path = objectify.ObjectPath("root.c1[-2].c2")
1220 self.assertRaises(AttributeError, path, root)
1221
1222 path = objectify.ObjectPath("root.c1[0].c2[-4]")
1223 self.assertRaises(AttributeError, path, root)
1224
1226 root = self.XML(xml_str)
1227 path = objectify.ObjectPath( "{objectified}root.c1.c2" )
1228 self.assertEquals(root.c1.c2.text, path.find(root).text)
1229 path = objectify.ObjectPath( "{objectified}root.{objectified}c1.c2" )
1230 self.assertEquals(root.c1.c2.text, path.find(root).text)
1231 path = objectify.ObjectPath( "root.{objectified}c1.{objectified}c2" )
1232 self.assertEquals(root.c1.c2.text, path.find(root).text)
1233 path = objectify.ObjectPath( "root.c1.{objectified}c2" )
1234 self.assertEquals(root.c1.c2.text, path.find(root).text)
1235 path = objectify.ObjectPath( "root.c1.{otherNS}c2" )
1236 self.assertEquals(getattr(root.c1, '{otherNS}c2').text,
1237 path.find(root).text)
1238
1240 root = self.XML(xml_str)
1241 path = objectify.ObjectPath( ['{objectified}root', 'c1', 'c2'] )
1242 self.assertEquals(root.c1.c2.text, path.find(root).text)
1243 path = objectify.ObjectPath( ['{objectified}root', '{objectified}c1', 'c2'] )
1244 self.assertEquals(root.c1.c2.text, path.find(root).text)
1245 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2'] )
1246 self.assertEquals(root.c1.c2.text, path.find(root).text)
1247 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2[2]'] )
1248 self.assertEquals(root.c1.c2[2].text, path.find(root).text)
1249 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2'] )
1250 self.assertEquals(root.c1.c2.text, path.find(root).text)
1251 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2[2]'] )
1252 self.assertEquals(root.c1.c2[2].text, path.find(root).text)
1253 path = objectify.ObjectPath( ['root', 'c1', '{otherNS}c2'] )
1254 self.assertEquals(getattr(root.c1, '{otherNS}c2').text,
1255 path.find(root).text)
1256
1258 root = self.XML(xml_str)
1259 path = objectify.ObjectPath( "root.c1.c2" )
1260 self.assertEquals(root.c1.c2.text, path.find(root).text)
1261 self.assertEquals("1", root.c1.c2[1].text)
1262
1263 new_value = "my new value"
1264 path.setattr(root, new_value)
1265
1266 self.assertEquals(new_value, root.c1.c2.text)
1267 self.assertEquals(new_value, path(root).text)
1268 self.assertEquals("1", root.c1.c2[1].text)
1269
1271 root = self.XML(xml_str)
1272 path = objectify.ObjectPath( "root.c1.c2" )
1273 self.assertEquals(root.c1.c2.text, path.find(root).text)
1274 self.assertEquals("1", root.c1.c2[1].text)
1275
1276 new_el = self.Element("{objectified}test")
1277 etree.SubElement(new_el, "{objectified}sub", myattr="ATTR").a = "TEST"
1278 path.setattr(root, new_el.sub)
1279
1280 self.assertEquals("ATTR", root.c1.c2.get("myattr"))
1281 self.assertEquals("TEST", root.c1.c2.a.text)
1282 self.assertEquals("TEST", path(root).a.text)
1283 self.assertEquals("1", root.c1.c2[1].text)
1284
1286 root = self.XML(xml_str)
1287 path = objectify.ObjectPath( "root.c1.c99" )
1288 self.assertRaises(AttributeError, path.find, root)
1289
1290 new_value = "my new value"
1291 path.setattr(root, new_value)
1292
1293 self.assertEquals(1, len(root.c1.c99))
1294 self.assertEquals(new_value, root.c1.c99.text)
1295 self.assertEquals(new_value, path(root).text)
1296
1298 root = self.XML(xml_str)
1299 path = objectify.ObjectPath( "root.c1.c99" )
1300 self.assertRaises(AttributeError, path.find, root)
1301
1302 new_el = self.Element("{objectified}test")
1303 etree.SubElement(new_el, "{objectified}sub", myattr="ATTR").a = "TEST"
1304 path.setattr(root, new_el.sub)
1305
1306 self.assertEquals(1, len(root.c1.c99))
1307 self.assertEquals("ATTR", root.c1.c99.get("myattr"))
1308 self.assertEquals("TEST", root.c1.c99.a.text)
1309 self.assertEquals("TEST", path(root).a.text)
1310
1312 root = self.XML(xml_str)
1313 path = objectify.ObjectPath( "root.c1.c99" )
1314 self.assertRaises(AttributeError, path.find, root)
1315
1316 new_el = self.Element("{objectified}test")
1317 new_el.a = ["TEST1", "TEST2"]
1318 new_el.a[0].set("myattr", "ATTR1")
1319 new_el.a[1].set("myattr", "ATTR2")
1320
1321 path.setattr(root, list(new_el.a))
1322
1323 self.assertEquals(2, len(root.c1.c99))
1324 self.assertEquals("ATTR1", root.c1.c99[0].get("myattr"))
1325 self.assertEquals("TEST1", root.c1.c99[0].text)
1326 self.assertEquals("ATTR2", root.c1.c99[1].get("myattr"))
1327 self.assertEquals("TEST2", root.c1.c99[1].text)
1328 self.assertEquals("TEST1", path(root).text)
1329
1331 root = self.XML(xml_str)
1332 path = objectify.ObjectPath( "root.c1.c2" )
1333 self.assertEquals(3, len(root.c1.c2))
1334 path.addattr(root, "test")
1335 self.assertEquals(4, len(root.c1.c2))
1336 self.assertEquals(["0", "1", "2", "test"],
1337 [el.text for el in root.c1.c2])
1338
1340 root = self.XML(xml_str)
1341 path = objectify.ObjectPath( "root.c1.c2" )
1342 self.assertEquals(3, len(root.c1.c2))
1343
1344 new_el = self.Element("{objectified}test")
1345 etree.SubElement(new_el, "{objectified}sub").a = "TEST"
1346
1347 path.addattr(root, new_el.sub)
1348 self.assertEquals(4, len(root.c1.c2))
1349 self.assertEquals("TEST", root.c1.c2[3].a.text)
1350 self.assertEquals(["0", "1", "2"],
1351 [el.text for el in root.c1.c2[:3]])
1352
1354 root = self.XML(xml_str)
1355 path = objectify.ObjectPath( "root.c1.c99" )
1356 self.assertRaises(AttributeError, path.find, root)
1357
1358 new_value = "my new value"
1359 path.addattr(root, new_value)
1360
1361 self.assertEquals(1, len(root.c1.c99))
1362 self.assertEquals(new_value, root.c1.c99.text)
1363 self.assertEquals(new_value, path(root).text)
1364
1366 root = self.XML(xml_str)
1367 path = objectify.ObjectPath( "root.c1.c99" )
1368 self.assertRaises(AttributeError, path.find, root)
1369
1370 new_el = self.Element("{objectified}test")
1371 etree.SubElement(new_el, "{objectified}sub", myattr="ATTR").a = "TEST"
1372
1373 path.addattr(root, new_el.sub)
1374 self.assertEquals(1, len(root.c1.c99))
1375 self.assertEquals("TEST", root.c1.c99.a.text)
1376 self.assertEquals("TEST", path(root).a.text)
1377 self.assertEquals("ATTR", root.c1.c99.get("myattr"))
1378
1380 root = self.XML(xml_str)
1381 path = objectify.ObjectPath( "root.c1.c99" )
1382 self.assertRaises(AttributeError, path.find, root)
1383
1384 new_el = self.Element("{objectified}test")
1385 new_el.a = ["TEST1", "TEST2"]
1386
1387 self.assertEquals(2, len(new_el.a))
1388
1389 path.addattr(root, list(new_el.a))
1390 self.assertEquals(2, len(root.c1.c99))
1391 self.assertEquals("TEST1", root.c1.c99.text)
1392 self.assertEquals("TEST2", path(root)[1].text)
1393
1395 root = self.XML(xml_str)
1396 self.assertEquals(
1397 ['{objectified}root', '{objectified}root.c1',
1398 '{objectified}root.c1.c2',
1399 '{objectified}root.c1.c2[1]', '{objectified}root.c1.c2[2]',
1400 '{objectified}root.c1.{otherNS}c2', '{objectified}root.c1.{}c2'],
1401 root.descendantpaths())
1402
1404 root = self.XML(xml_str)
1405 self.assertEquals(
1406 ['{objectified}c1', '{objectified}c1.c2',
1407 '{objectified}c1.c2[1]', '{objectified}c1.c2[2]',
1408 '{objectified}c1.{otherNS}c2', '{objectified}c1.{}c2'],
1409 root.c1.descendantpaths())
1410
1412 root = self.XML(xml_str)
1413 self.assertEquals(
1414 ['root.{objectified}c1', 'root.{objectified}c1.c2',
1415 'root.{objectified}c1.c2[1]', 'root.{objectified}c1.c2[2]',
1416 'root.{objectified}c1.{otherNS}c2',
1417 'root.{objectified}c1.{}c2'],
1418 root.c1.descendantpaths('root'))
1419
1421 import pickle
1422
1423 root = self.XML(xml_str)
1424 out = StringIO()
1425 pickle.dump(root, out)
1426
1427 new_root = pickle.loads(out.getvalue())
1428 self.assertEquals(
1429 etree.tostring(new_root),
1430 etree.tostring(root))
1431
1433 suite = unittest.TestSuite()
1434 suite.addTests([unittest.makeSuite(ObjectifyTestCase)])
1435 suite.addTests(
1436 [doctest.DocFileSuite('../../../doc/objectify.txt')])
1437 return suite
1438
1439 if __name__ == '__main__':
1440 unittest.main()
1441