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 objectclass2pytype = {
44
45 objectify.IntElement: "int",
46 objectify.LongElement: "long",
47 objectify.FloatElement: "float",
48 objectify.BoolElement: "bool",
49 objectify.StringElement: "str",
50
51 }
52
53 pytype2objclass = dict(( (objectclass2pytype[k], k) for k in objectclass2pytype))
54
55 xml_str = '''\
56 <obj:root xmlns:obj="objectified" xmlns:other="otherNS">
57 <obj:c1 a1="A1" a2="A2" other:a3="A3">
58 <obj:c2>0</obj:c2>
59 <obj:c2>1</obj:c2>
60 <obj:c2>2</obj:c2>
61 <other:c2>3</other:c2>
62 <c2>3</c2>
63 </obj:c1>
64 </obj:root>'''
65
67 """Test cases for lxml.objectify
68 """
69 etree = etree
70
73
84
90
94
99
106
116
121
127
135
146
150
155
162
172
177
183
191
202
204
205 value = objectify.DataElement(23, _pytype="str", _xsi="foobar",
206 attrib={"gnu": "muh", "cat": "meeow",
207 "dog": "wuff"},
208 bird="tchilp", dog="grrr")
209 self.assertEquals(value.get("gnu"), "muh")
210 self.assertEquals(value.get("cat"), "meeow")
211 self.assertEquals(value.get("dog"), "grrr")
212 self.assertEquals(value.get("bird"), "tchilp")
213
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, _pytype="NoneType")
234 self.assert_(isinstance(value, objectify.NoneElement))
235 self.assertEquals(value.get(XML_SCHEMA_NIL_ATTR), "true")
236 self.assertEquals(value.text, None)
237 self.assertEquals(value.pyval, None)
238 for attr in arg.attrib:
239
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")
250 self.assert_(isinstance(value, objectify.IntElement))
251 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
252 for attr in arg.attrib:
253 if not attr == objectify.PYTYPE_ATTRIBUTE:
254 self.assertEquals(value.get(attr), arg.get(attr))
255
257
258
259 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
260 attrib={"gnu": "muh", "cat": "meeow",
261 "dog": "wuff"},
262 bird="tchilp", dog="grrr")
263 value = objectify.DataElement(arg, _xsi="xsd:int")
264 self.assert_(isinstance(value, objectify.IntElement))
265 self.assertEquals(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
266 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
267 for attr in arg.attrib:
268 if not attr in [objectify.PYTYPE_ATTRIBUTE,
269 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
270 self.assertEquals(value.get(attr), arg.get(attr))
271
273
274
275 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
276 attrib={"gnu": "muh", "cat": "meeow",
277 "dog": "wuff"},
278 bird="tchilp", dog="grrr")
279 value = objectify.DataElement(arg, _pytype="int", _xsi="xsd:int")
280 self.assert_(isinstance(value, objectify.IntElement))
281 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
282 self.assertEquals(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
283 for attr in arg.attrib:
284 if not attr in [objectify.PYTYPE_ATTRIBUTE,
285 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
286 self.assertEquals(value.get(attr), arg.get(attr))
287
291
295
300
305
309
313
317
322
324 root = self.XML(xml_str)
325 self.assertEquals("0", getattr(root.c1, "{objectified}c2").text)
326 self.assertEquals("3", getattr(root.c1, "{otherNS}c2").text)
327
329 root = self.XML(xml_str)
330 self.assertRaises(AttributeError, getattr, root.c1, "NOT_THERE")
331 self.assertRaises(AttributeError, getattr, root.c1, "{unknownNS}c2")
332
339
341 root = self.XML(xml_str)
342 self.assertEquals(1, len(root.c1))
343
344 new_el = self.Element("test", myattr="5")
345 root.addattr("c1", new_el)
346 self.assertEquals(2, len(root.c1))
347 self.assertEquals(None, root.c1[0].get("myattr"))
348 self.assertEquals("5", root.c1[1].get("myattr"))
349
351 root = self.XML(xml_str)
352 self.assertEquals(1, len(root.c1))
353
354 new_el = self.Element("test")
355 self.etree.SubElement(new_el, "a", myattr="A")
356 self.etree.SubElement(new_el, "a", myattr="B")
357
358 root.addattr("c1", list(new_el.a))
359 self.assertEquals(3, len(root.c1))
360 self.assertEquals(None, root.c1[0].get("myattr"))
361 self.assertEquals("A", root.c1[1].get("myattr"))
362 self.assertEquals("B", root.c1[2].get("myattr"))
363
370
372 root = self.XML(xml_str)
373 self.assertEquals("0", root.c1.c2[0].text)
374 self.assertEquals("1", root.c1.c2[1].text)
375 self.assertEquals("2", root.c1.c2[2].text)
376 self.assertRaises(IndexError, itemgetter(3), root.c1.c2)
377
379 root = self.XML(xml_str)
380 self.assertEquals("0", root.c1.c2[0].text)
381 self.assertEquals("0", root.c1.c2[-3].text)
382 self.assertEquals("1", root.c1.c2[-2].text)
383 self.assertEquals("2", root.c1.c2[-1].text)
384 self.assertRaises(IndexError, itemgetter(-4), root.c1.c2)
385
387 root = self.XML(xml_str)
388 self.assertEquals(1, len(root))
389 self.assertEquals(1, len(root.c1))
390 self.assertEquals(3, len(root.c1.c2))
391
400
406
416
421
426
428 Element = self.Element
429 SubElement = self.etree.SubElement
430 root = Element("root")
431 root.c = ["c1", "c2"]
432
433 c1 = root.c[0]
434 c2 = root.c[1]
435
436 self.assertEquals([c1,c2], list(root.c))
437 self.assertEquals(["c1", "c2"],
438 [ c.text for c in root.c ])
439
440 root2 = Element("root2")
441 root2.el = [ "test", "test" ]
442 self.assertEquals(["test", "test"],
443 [ el.text for el in root2.el ])
444
445 root.c = [ root2.el, root2.el ]
446 self.assertEquals(["test", "test"],
447 [ c.text for c in root.c ])
448 self.assertEquals(["test", "test"],
449 [ el.text for el in root2.el ])
450
451 root.c[:] = [ c1, c2, c2, c1 ]
452 self.assertEquals(["c1", "c2", "c2", "c1"],
453 [ c.text for c in root.c ])
454
463
472
474
475 Element = self.Element
476 SubElement = self.etree.SubElement
477 root = Element("root")
478
479 root["text"] = "TEST"
480 self.assertEquals(["TEST"],
481 [ c.text for c in root["text"] ])
482
483 root["tail"] = "TEST"
484 self.assertEquals(["TEST"],
485 [ c.text for c in root["tail"] ])
486
487 root["pyval"] = "TEST"
488 self.assertEquals(["TEST"],
489 [ c.text for c in root["pyval"] ])
490
491 root["tag"] = "TEST"
492 self.assertEquals(["TEST"],
493 [ c.text for c in root["tag"] ])
494
502
504 XML = self.XML
505 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')
506 self.assertEquals(2, len(root.findall(".//{X}b")))
507 self.assertEquals(3, len(root.findall(".//b")))
508 self.assertEquals(2, len(root.findall("b")))
509
517
531
537
549
558
565
572
579
581 Element = self.Element
582 SubElement = self.etree.SubElement
583 root = Element("{objectified}root")
584 root.s = "test"
585
586 self.assertEquals("test" * 5, root.s * 5)
587 self.assertEquals(5 * "test", 5 * root.s)
588
589 self.assertRaises(TypeError, operator.mul, root.s, "honk")
590 self.assertRaises(TypeError, operator.mul, "honk", root.s)
591
601
606
611
616
623
628
635
640
649
658
664
673
675 pyval = 1
676 pytype = "NoneType"
677 objclass = objectify.NoneElement
678 value = objectify.DataElement(pyval, _pytype=pytype)
679 self.assert_(isinstance(value, objclass),
680 "DataElement(%s, _pytype='%s') returns %s, expected %s"
681 % (pyval, pytype, type(value), objclass))
682 self.assertEquals(value.text, None)
683 self.assertEquals(value.pyval, None)
684
686
687 pyval = 1
688 pytype = "none"
689 objclass = objectify.NoneElement
690 value = objectify.DataElement(pyval, _pytype=pytype)
691 self.assert_(isinstance(value, objclass),
692 "DataElement(%s, _pytype='%s') returns %s, expected %s"
693 % (pyval, pytype, type(value), objclass))
694 self.assertEquals(value.text, None)
695 self.assertEquals(value.pyval, None)
696
702 root = Element("{objectified}root")
703 root.myfloat = MyFloat(5.5)
704 self.assert_(isinstance(root.myfloat, objectify.FloatElement))
705 self.assertEquals(root.myfloat.get(objectify.PYTYPE_ATTRIBUTE), None)
706
708 class MyFloat(float):
709 pass
710 value = objectify.DataElement(MyFloat(5.5))
711 self.assert_(isinstance(value, objectify.FloatElement))
712 self.assertEquals(value, 5.5)
713 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), None)
714
716 XML = self.XML
717 root = XML('''\
718 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
719 <b xsi:type="boolean">true</b>
720 <b xsi:type="boolean">false</b>
721 <b xsi:type="boolean">1</b>
722 <b xsi:type="boolean">0</b>
723
724 <f xsi:type="float">5</f>
725 <f xsi:type="double">5</f>
726
727 <s xsi:type="string">5</s>
728 <s xsi:type="normalizedString">5</s>
729 <s xsi:type="token">5</s>
730 <s xsi:type="language">5</s>
731 <s xsi:type="Name">5</s>
732 <s xsi:type="NCName">5</s>
733 <s xsi:type="ID">5</s>
734 <s xsi:type="IDREF">5</s>
735 <s xsi:type="ENTITY">5</s>
736 <s xsi:type="NMTOKEN">5</s>
737
738 <l xsi:type="integer">5</l>
739 <l xsi:type="nonPositiveInteger">5</l>
740 <l xsi:type="negativeInteger">5</l>
741 <l xsi:type="long">5</l>
742 <l xsi:type="nonNegativeInteger">5</l>
743 <l xsi:type="unsignedLong">5</l>
744 <l xsi:type="unsignedInt">5</l>
745 <l xsi:type="positiveInteger">5</l>
746
747 <i xsi:type="int">5</i>
748 <i xsi:type="short">5</i>
749 <i xsi:type="byte">5</i>
750 <i xsi:type="unsignedShort">5</i>
751 <i xsi:type="unsignedByte">5</i>
752
753 <n xsi:nil="true"/>
754 </root>
755 ''')
756
757 for b in root.b:
758 self.assert_(isinstance(b, objectify.BoolElement))
759 self.assertEquals(True, root.b[0])
760 self.assertEquals(False, root.b[1])
761 self.assertEquals(True, root.b[2])
762 self.assertEquals(False, root.b[3])
763
764 for f in root.f:
765 self.assert_(isinstance(f, objectify.FloatElement))
766 self.assertEquals(5, f)
767
768 for s in root.s:
769 self.assert_(isinstance(s, objectify.StringElement))
770 self.assertEquals("5", s)
771
772 for l in root.l:
773 self.assert_(isinstance(l, objectify.LongElement))
774 self.assertEquals(5L, l)
775
776 for i in root.i:
777 self.assert_(isinstance(i, objectify.IntElement))
778 self.assertEquals(5, i)
779
780 self.assert_(isinstance(root.n, objectify.NoneElement))
781 self.assertEquals(None, root.n)
782
784 XML = self.XML
785 root = XML('''\
786 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
787 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
788 <b xsi:type="xsd:boolean">true</b>
789 <b xsi:type="xsd:boolean">false</b>
790 <b xsi:type="xsd:boolean">1</b>
791 <b xsi:type="xsd:boolean">0</b>
792
793 <f xsi:type="xsd:float">5</f>
794 <f xsi:type="xsd:double">5</f>
795
796 <s xsi:type="xsd:string">5</s>
797 <s xsi:type="xsd:normalizedString">5</s>
798 <s xsi:type="xsd:token">5</s>
799 <s xsi:type="xsd:language">5</s>
800 <s xsi:type="xsd:Name">5</s>
801 <s xsi:type="xsd:NCName">5</s>
802 <s xsi:type="xsd:ID">5</s>
803 <s xsi:type="xsd:IDREF">5</s>
804 <s xsi:type="xsd:ENTITY">5</s>
805 <s xsi:type="xsd:NMTOKEN">5</s>
806
807 <l xsi:type="xsd:integer">5</l>
808 <l xsi:type="xsd:nonPositiveInteger">5</l>
809 <l xsi:type="xsd:negativeInteger">5</l>
810 <l xsi:type="xsd:long">5</l>
811 <l xsi:type="xsd:nonNegativeInteger">5</l>
812 <l xsi:type="xsd:unsignedLong">5</l>
813 <l xsi:type="xsd:unsignedInt">5</l>
814 <l xsi:type="xsd:positiveInteger">5</l>
815
816 <i xsi:type="xsd:int">5</i>
817 <i xsi:type="xsd:short">5</i>
818 <i xsi:type="xsd:byte">5</i>
819 <i xsi:type="xsd:unsignedShort">5</i>
820 <i xsi:type="xsd:unsignedByte">5</i>
821
822 <n xsi:nil="true"/>
823 </root>
824 ''')
825
826 for b in root.b:
827 self.assert_(isinstance(b, objectify.BoolElement))
828 self.assertEquals(True, root.b[0])
829 self.assertEquals(False, root.b[1])
830 self.assertEquals(True, root.b[2])
831 self.assertEquals(False, root.b[3])
832
833 for f in root.f:
834 self.assert_(isinstance(f, objectify.FloatElement))
835 self.assertEquals(5, f)
836
837 for s in root.s:
838 self.assert_(isinstance(s, objectify.StringElement))
839 self.assertEquals("5", s)
840
841 for l in root.l:
842 self.assert_(isinstance(l, objectify.LongElement))
843 self.assertEquals(5L, l)
844
845 for i in root.i:
846 self.assert_(isinstance(i, objectify.IntElement))
847 self.assertEquals(5, i)
848
849 self.assert_(isinstance(root.n, objectify.NoneElement))
850 self.assertEquals(None, root.n)
851
853 XML = self.XML
854 root = XML(u'<root><b>why</b><b>try</b></root>')
855 strs = [ str(s) for s in root.b ]
856 self.assertEquals(["why", "try"],
857 strs)
858
879
900
924
930
937
941
943 XML = self.XML
944 root = XML(u'''\
945 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
946 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
947 <b>5</b>
948 <b>test</b>
949 <c>1.1</c>
950 <c>\uF8D2</c>
951 <x>true</x>
952 <n xsi:nil="true" />
953 <n></n>
954 <b xsi:type="double">5</b>
955 <b xsi:type="float">5</b>
956 <s xsi:type="string">23</s>
957 <s py:pytype="str">42</s>
958 <f py:pytype="float">300</f>
959 <l py:pytype="long">2</l>
960 </a>
961 ''')
962 objectify.annotate(root)
963
964 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
965 for c in root.iterchildren() ]
966 self.assertEquals("int", child_types[ 0])
967 self.assertEquals("str", child_types[ 1])
968 self.assertEquals("float", child_types[ 2])
969 self.assertEquals("str", child_types[ 3])
970 self.assertEquals("bool", child_types[ 4])
971 self.assertEquals("NoneType", child_types[ 5])
972 self.assertEquals(None, child_types[ 6])
973 self.assertEquals("float", child_types[ 7])
974 self.assertEquals("float", child_types[ 8])
975 self.assertEquals("str", child_types[ 9])
976 self.assertEquals("int", child_types[10])
977 self.assertEquals("int", child_types[11])
978 self.assertEquals("int", child_types[12])
979
980 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
981
1001
1003 XML = self.XML
1004 root = XML(u'''\
1005 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1006 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1007 <b>5</b>
1008 <b>test</b>
1009 <c>1.1</c>
1010 <c>\uF8D2</c>
1011 <x>true</x>
1012 <n xsi:nil="true" />
1013 <n></n>
1014 <b xsi:type="double">5</b>
1015 <b xsi:type="float">5</b>
1016 <s xsi:type="string">23</s>
1017 <s py:pytype="str">42</s>
1018 <f py:pytype="float">300</f>
1019 <l py:pytype="long">2</l>
1020 </a>
1021 ''')
1022 objectify.annotate(root, ignore_old=False)
1023
1024 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1025 for c in root.iterchildren() ]
1026 self.assertEquals("int", child_types[ 0])
1027 self.assertEquals("str", child_types[ 1])
1028 self.assertEquals("float", child_types[ 2])
1029 self.assertEquals("str", child_types[ 3])
1030 self.assertEquals("bool", child_types[ 4])
1031 self.assertEquals("NoneType", child_types[ 5])
1032 self.assertEquals(None, child_types[ 6])
1033 self.assertEquals("float", child_types[ 7])
1034 self.assertEquals("float", child_types[ 8])
1035 self.assertEquals("str", child_types[ 9])
1036 self.assertEquals("str", child_types[10])
1037 self.assertEquals("float", child_types[11])
1038 self.assertEquals("long", child_types[12])
1039
1040 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1041
1043 XML = self.XML
1044 root = XML(u'''\
1045 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1046 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1047 <b>5</b>
1048 <b>test</b>
1049 <c>1.1</c>
1050 <c>\uF8D2</c>
1051 <x>true</x>
1052 <n xsi:nil="true" />
1053 <n></n>
1054 <b xsi:type="double">5</b>
1055 <b xsi:type="float">5</b>
1056 <s xsi:type="string">23</s>
1057 <s py:pytype="str">42</s>
1058 <f py:pytype="float">300</f>
1059 <l py:pytype="long">2</l>
1060 </a>
1061 ''')
1062 objectify.xsiannotate(root)
1063
1064 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1065 for c in root.iterchildren() ]
1066 self.assertEquals("xsd:int", child_types[ 0])
1067 self.assertEquals("xsd:string", child_types[ 1])
1068 self.assertEquals("xsd:double", child_types[ 2])
1069 self.assertEquals("xsd:string", child_types[ 3])
1070 self.assertEquals("xsd:boolean", child_types[ 4])
1071 self.assertEquals(None, child_types[ 5])
1072 self.assertEquals(None, child_types[ 6])
1073 self.assertEquals("xsd:int", child_types[ 7])
1074 self.assertEquals("xsd:int", child_types[ 8])
1075 self.assertEquals("xsd:int", child_types[ 9])
1076 self.assertEquals("xsd:string", child_types[10])
1077 self.assertEquals("xsd:double", child_types[11])
1078 self.assertEquals("xsd:integer", child_types[12])
1079
1080 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1081
1083 XML = self.XML
1084 root = XML(u'''\
1085 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1086 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1087 <b>5</b>
1088 <b>test</b>
1089 <c>1.1</c>
1090 <c>\uF8D2</c>
1091 <x>true</x>
1092 <n xsi:nil="true" />
1093 <n></n>
1094 <b xsi:type="double">5</b>
1095 <b xsi:type="float">5</b>
1096 <s xsi:type="string">23</s>
1097 <s py:pytype="str">42</s>
1098 <f py:pytype="float">300</f>
1099 <l py:pytype="long">2</l>
1100 </a>
1101 ''')
1102 objectify.xsiannotate(root, ignore_old=False)
1103
1104 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1105 for c in root.iterchildren() ]
1106 self.assertEquals("xsd:int", child_types[ 0])
1107 self.assertEquals("xsd:string", child_types[ 1])
1108 self.assertEquals("xsd:double", child_types[ 2])
1109 self.assertEquals("xsd:string", child_types[ 3])
1110 self.assertEquals("xsd:boolean", child_types[ 4])
1111 self.assertEquals(None, child_types[ 5])
1112 self.assertEquals(None, child_types[ 6])
1113 self.assertEquals("xsd:double", child_types[ 7])
1114 self.assertEquals("xsd:float", child_types[ 8])
1115 self.assertEquals("xsd:string", child_types[ 9])
1116 self.assertEquals("xsd:string", child_types[10])
1117 self.assertEquals("xsd:double", child_types[11])
1118 self.assertEquals("xsd:integer", child_types[12])
1119
1120 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1121
1123 XML = self.XML
1124 root = XML(u'''\
1125 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1126 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1127 <b>5</b>
1128 <b>test</b>
1129 <c>1.1</c>
1130 <c>\uF8D2</c>
1131 <x>true</x>
1132 <n xsi:nil="true" />
1133 <n></n>
1134 <b xsi:type="double">5</b>
1135 <b xsi:type="float">5</b>
1136 <s xsi:type="string">23</s>
1137 <s py:pytype="str">42</s>
1138 <f py:pytype="float">300</f>
1139 <l py:pytype="long">2</l>
1140 </a>
1141 ''')
1142 objectify.deannotate(root)
1143
1144 for c in root.getiterator():
1145 self.assertEquals(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1146 self.assertEquals(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1147
1148 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1149
1151 XML = self.XML
1152 root = XML(u'''\
1153 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1154 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1155 <b>5</b>
1156 <b>test</b>
1157 <c>1.1</c>
1158 <c>\uF8D2</c>
1159 <x>true</x>
1160 <n xsi:nil="true" />
1161 <n></n>
1162 <b xsi:type="double">5</b>
1163 <b xsi:type="float">5</b>
1164 <s xsi:type="string">23</s>
1165 <s py:pytype="str">42</s>
1166 <f py:pytype="float">300</f>
1167 <l py:pytype="long">2</l>
1168 </a>
1169 ''')
1170 objectify.xsiannotate(root)
1171 objectify.deannotate(root, xsi=False)
1172
1173 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1174 for c in root.iterchildren() ]
1175 self.assertEquals("xsd:int", child_types[ 0])
1176 self.assertEquals("xsd:string", child_types[ 1])
1177 self.assertEquals("xsd:double", child_types[ 2])
1178 self.assertEquals("xsd:string", child_types[ 3])
1179 self.assertEquals("xsd:boolean", child_types[ 4])
1180 self.assertEquals(None, child_types[ 5])
1181 self.assertEquals(None, child_types[ 6])
1182 self.assertEquals("xsd:int", child_types[ 7])
1183 self.assertEquals("xsd:int", child_types[ 8])
1184 self.assertEquals("xsd:int", child_types[ 9])
1185 self.assertEquals("xsd:string", child_types[10])
1186 self.assertEquals("xsd:double", child_types[11])
1187 self.assertEquals("xsd:integer", child_types[12])
1188
1189 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1190
1191 for c in root.getiterator():
1192 self.assertEquals(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1193
1195 XML = self.XML
1196 root = XML(u'''\
1197 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1198 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1199 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1200 <b>5</b>
1201 <b>test</b>
1202 <c>1.1</c>
1203 <c>\uF8D2</c>
1204 <x>true</x>
1205 <n xsi:nil="true" />
1206 <n></n>
1207 <b xsi:type="xsd:double">5</b>
1208 <b xsi:type="xsd:float">5</b>
1209 <s xsi:type="xsd:string">23</s>
1210 <s py:pytype="str">42</s>
1211 <f py:pytype="float">300</f>
1212 <l py:pytype="long">2</l>
1213 </a>
1214 ''')
1215 objectify.annotate(root)
1216 objectify.deannotate(root, pytype=False)
1217
1218 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1219 for c in root.iterchildren() ]
1220 self.assertEquals("int", child_types[ 0])
1221 self.assertEquals("str", child_types[ 1])
1222 self.assertEquals("float", child_types[ 2])
1223 self.assertEquals("str", child_types[ 3])
1224 self.assertEquals("bool", child_types[ 4])
1225 self.assertEquals("NoneType", child_types[ 5])
1226 self.assertEquals(None, child_types[ 6])
1227 self.assertEquals("float", child_types[ 7])
1228 self.assertEquals("float", child_types[ 8])
1229 self.assertEquals("str", child_types[ 9])
1230 self.assertEquals("int", child_types[10])
1231 self.assertEquals("int", child_types[11])
1232 self.assertEquals("int", child_types[12])
1233
1234 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1235
1236 for c in root.getiterator():
1237 self.assertEquals(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1238
1240 XML = self.XML
1241 root = XML(u'''\
1242 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1243 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1244 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1245 <b xsi:type="xsd:int">5</b>
1246 <b xsi:type="xsd:string">test</b>
1247 <c xsi:type="xsd:float">1.1</c>
1248 <c xsi:type="xsd:string">\uF8D2</c>
1249 <x xsi:type="xsd:boolean">true</x>
1250 <n xsi:nil="true" />
1251 <n></n>
1252 <b xsi:type="xsd:double">5</b>
1253 <b xsi:type="xsd:float">5</b>
1254 <s xsi:type="xsd:string">23</s>
1255 <s xsi:type="xsd:string">42</s>
1256 <f xsi:type="xsd:float">300</f>
1257 <l xsi:type="xsd:long">2</l>
1258 </a>
1259 ''')
1260 objectify.annotate(root)
1261 objectify.deannotate(root, xsi=False)
1262
1263 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1264 for c in root.iterchildren() ]
1265 self.assertEquals("xsd:int", child_types[ 0])
1266 self.assertEquals("xsd:string", child_types[ 1])
1267 self.assertEquals("xsd:float", child_types[ 2])
1268 self.assertEquals("xsd:string", child_types[ 3])
1269 self.assertEquals("xsd:boolean", child_types[ 4])
1270 self.assertEquals(None, child_types[ 5])
1271 self.assertEquals(None, child_types[ 6])
1272 self.assertEquals("xsd:double", child_types[ 7])
1273 self.assertEquals("xsd:float", child_types[ 8])
1274 self.assertEquals("xsd:string", child_types[ 9])
1275 self.assertEquals("xsd:string", child_types[10])
1276 self.assertEquals("xsd:float", child_types[11])
1277 self.assertEquals("xsd:long", child_types[12])
1278
1279 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1280
1281 for c in root.getiterator():
1282 self.assertEquals(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1283
1285 XML = self.XML
1286
1287 xml = u'''\
1288 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1289 <b>5</b>
1290 <b>test</b>
1291 <c>1.1</c>
1292 <c>\uF8D2</c>
1293 <x>true</x>
1294 <n xsi:nil="true" />
1295 <n></n>
1296 <b xsi:type="double">5</b>
1297 </a>
1298 '''
1299
1300 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1301 objectify.setPytypeAttributeTag("{TEST}test")
1302
1303 root = XML(xml)
1304 objectify.annotate(root)
1305
1306 attribs = root.xpath("//@py:%s" % pytype_name, {"py" : pytype_ns})
1307 self.assertEquals(0, len(attribs))
1308 attribs = root.xpath("//@py:test", {"py" : "TEST"})
1309 self.assertEquals(7, len(attribs))
1310
1311 objectify.setPytypeAttributeTag()
1312 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1313
1314 self.assertNotEqual("test", pytype_ns.lower())
1315 self.assertNotEqual("test", pytype_name.lower())
1316
1317 root = XML(xml)
1318 attribs = root.xpath("//@py:%s" % pytype_name, {"py" : pytype_ns})
1319 self.assertEquals(0, len(attribs))
1320
1321 objectify.annotate(root)
1322 attribs = root.xpath("//@py:%s" % pytype_name, {"py" : pytype_ns})
1323 self.assertEquals(7, len(attribs))
1324
1334
1335 def checkMyType(s):
1336 return True
1337
1338 pytype = objectify.PyType("mytype", checkMyType, NewType)
1339 pytype.register()
1340 self.assert_(pytype in objectify.getRegisteredTypes())
1341 pytype.unregister()
1342
1343 pytype.register(before = [objectify.getRegisteredTypes()[0].name])
1344 self.assertEquals(pytype, objectify.getRegisteredTypes()[0])
1345 pytype.unregister()
1346
1347 pytype.register(after = [objectify.getRegisteredTypes()[0].name])
1348 self.assertNotEqual(pytype, objectify.getRegisteredTypes()[0])
1349 pytype.unregister()
1350
1351 self.assertRaises(ValueError, pytype.register,
1352 before = [objectify.getRegisteredTypes()[0].name],
1353 after = [objectify.getRegisteredTypes()[1].name])
1354
1355 finally:
1356 for pytype in objectify.getRegisteredTypes():
1357 pytype.unregister()
1358 for pytype in orig_types:
1359 pytype.register()
1360
1366
1372
1378
1386
1405
1410
1415
1420
1425
1445
1447 root = self.XML(xml_str)
1448 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[0]'] )
1449 self.assertEquals(root.c1.c2.text, path(root).text)
1450
1451 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[2]'] )
1452 self.assertEquals(root.c1.c2[2].text, path(root).text)
1453
1454 path = objectify.ObjectPath( ['root', 'c1', 'c2[2]'] )
1455 self.assertEquals(root.c1.c2[2].text, path(root).text)
1456
1457 path = objectify.ObjectPath( ['root', 'c1', 'c2[-1]'] )
1458 self.assertEquals(root.c1.c2[-1].text, path(root).text)
1459
1460 path = objectify.ObjectPath( ['root', 'c1', 'c2[-3]'] )
1461 self.assertEquals(root.c1.c2[-3].text, path(root).text)
1462
1464 self.assertRaises(ValueError, objectify.ObjectPath,
1465 "root.c1[0].c2[-1-2]")
1466 self.assertRaises(ValueError, objectify.ObjectPath,
1467 ['root', 'c1[0]', 'c2[-1-2]'])
1468
1469 self.assertRaises(ValueError, objectify.ObjectPath,
1470 "root[2].c1.c2")
1471 self.assertRaises(ValueError, objectify.ObjectPath,
1472 ['root[2]', 'c1', 'c2'])
1473
1474 self.assertRaises(ValueError, objectify.ObjectPath,
1475 [])
1476 self.assertRaises(ValueError, objectify.ObjectPath,
1477 ['', '', ''])
1478
1480 root = self.XML(xml_str)
1481 path = objectify.ObjectPath("root.c1[9999].c2")
1482 self.assertRaises(AttributeError, path, root)
1483
1484 path = objectify.ObjectPath("root.c1[0].c2[9999]")
1485 self.assertRaises(AttributeError, path, root)
1486
1487 path = objectify.ObjectPath(".c1[9999].c2[0]")
1488 self.assertRaises(AttributeError, path, root)
1489
1490 path = objectify.ObjectPath("root.c1[-2].c2")
1491 self.assertRaises(AttributeError, path, root)
1492
1493 path = objectify.ObjectPath("root.c1[0].c2[-4]")
1494 self.assertRaises(AttributeError, path, root)
1495
1509
1511 root = self.XML(xml_str)
1512 path = objectify.ObjectPath( ['{objectified}root', 'c1', 'c2'] )
1513 self.assertEquals(root.c1.c2.text, path.find(root).text)
1514 path = objectify.ObjectPath( ['{objectified}root', '{objectified}c1', 'c2'] )
1515 self.assertEquals(root.c1.c2.text, path.find(root).text)
1516 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2'] )
1517 self.assertEquals(root.c1.c2.text, path.find(root).text)
1518 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2[2]'] )
1519 self.assertEquals(root.c1.c2[2].text, path.find(root).text)
1520 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2'] )
1521 self.assertEquals(root.c1.c2.text, path.find(root).text)
1522 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2[2]'] )
1523 self.assertEquals(root.c1.c2[2].text, path.find(root).text)
1524 path = objectify.ObjectPath( ['root', 'c1', '{otherNS}c2'] )
1525 self.assertEquals(getattr(root.c1, '{otherNS}c2').text,
1526 path.find(root).text)
1527
1540
1555
1567
1581
1583 root = self.XML(xml_str)
1584 path = objectify.ObjectPath( "root.c1.c99" )
1585 self.assertRaises(AttributeError, path.find, root)
1586
1587 new_el = self.Element("{objectified}test")
1588 new_el.a = ["TEST1", "TEST2"]
1589 new_el.a[0].set("myattr", "ATTR1")
1590 new_el.a[1].set("myattr", "ATTR2")
1591
1592 path.setattr(root, list(new_el.a))
1593
1594 self.assertEquals(2, len(root.c1.c99))
1595 self.assertEquals("ATTR1", root.c1.c99[0].get("myattr"))
1596 self.assertEquals("TEST1", root.c1.c99[0].text)
1597 self.assertEquals("ATTR2", root.c1.c99[1].get("myattr"))
1598 self.assertEquals("TEST2", root.c1.c99[1].text)
1599 self.assertEquals("TEST1", path(root).text)
1600
1609
1623
1635
1649
1664
1666 root = self.XML(xml_str)
1667 self.assertEquals(
1668 ['{objectified}root', '{objectified}root.c1',
1669 '{objectified}root.c1.c2',
1670 '{objectified}root.c1.c2[1]', '{objectified}root.c1.c2[2]',
1671 '{objectified}root.c1.{otherNS}c2', '{objectified}root.c1.{}c2'],
1672 root.descendantpaths())
1673
1675 root = self.XML(xml_str)
1676 self.assertEquals(
1677 ['{objectified}c1', '{objectified}c1.c2',
1678 '{objectified}c1.c2[1]', '{objectified}c1.c2[2]',
1679 '{objectified}c1.{otherNS}c2', '{objectified}c1.{}c2'],
1680 root.c1.descendantpaths())
1681
1683 root = self.XML(xml_str)
1684 self.assertEquals(
1685 ['root.{objectified}c1', 'root.{objectified}c1.c2',
1686 'root.{objectified}c1.c2[1]', 'root.{objectified}c1.c2[2]',
1687 'root.{objectified}c1.{otherNS}c2',
1688 'root.{objectified}c1.{}c2'],
1689 root.c1.descendantpaths('root'))
1690
1702
1703
1704
1709
1714
1719
1724
1729
1734
1739
1744
1749
1751 E = objectify.E
1752 DataElement = objectify.DataElement
1753 root = E.root("text", E.sub(E.subsub()), "tail", DataElement(1),
1754 DataElement(2.0))
1755 self.assert_(isinstance(root, objectify.ObjectifiedElement))
1756 self.assertEquals(root.text, "text")
1757 self.assert_(isinstance(root.sub, objectify.ObjectifiedElement))
1758 self.assertEquals(root.sub.tail, "tail")
1759 self.assert_(isinstance(root.sub.subsub, objectify.StringElement))
1760 self.assertEquals(len(root.value), 2)
1761 self.assert_(isinstance(root.value[0], objectify.IntElement))
1762 self.assert_(isinstance(root.value[1], objectify.FloatElement))
1763
1765 suite = unittest.TestSuite()
1766 suite.addTests([unittest.makeSuite(ObjectifyTestCase)])
1767 suite.addTests(
1768 [doctest.DocFileSuite('../../../doc/objectify.txt')])
1769 return suite
1770
1771 if __name__ == '__main__':
1772 print 'to test use test.py %s' % __file__
1773