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
13 from lxml import objectify
14
15 PYTYPE_NAMESPACE = "http://codespeak.net/lxml/objectify/pytype"
16 XML_SCHEMA_NS = "http://www.w3.org/2001/XMLSchema"
17 XML_SCHEMA_INSTANCE_NS = "http://www.w3.org/2001/XMLSchema-instance"
18 XML_SCHEMA_INSTANCE_TYPE_ATTR = "{%s}type" % XML_SCHEMA_INSTANCE_NS
19 XML_SCHEMA_NIL_ATTR = "{%s}nil" % XML_SCHEMA_INSTANCE_NS
20 DEFAULT_NSMAP = { "py" : PYTYPE_NAMESPACE,
21 "xsi" : XML_SCHEMA_INSTANCE_NS,
22 "xsd" : XML_SCHEMA_NS}
23
24 objectclass2xsitype = {
25
26 objectify.IntElement: ("int", "short", "byte", "unsignedShort",
27 "unsignedByte",),
28 objectify.LongElement: ("integer", "nonPositiveInteger", "negativeInteger",
29 "long", "nonNegativeInteger", "unsignedLong",
30 "unsignedInt", "positiveInteger",),
31 objectify.FloatElement: ("float", "double"),
32 objectify.BoolElement: ("boolean",),
33 objectify.StringElement: ("string", "normalizedString", "token", "language",
34 "Name", "NCName", "ID", "IDREF", "ENTITY",
35 "NMTOKEN", ),
36
37 }
38
39 xsitype2objclass = dict(( (v, k) for k in objectclass2xsitype
40 for v in objectclass2xsitype[k] ))
41
42 objectclass2pytype = {
43
44 objectify.IntElement: "int",
45 objectify.LongElement: "long",
46 objectify.FloatElement: "float",
47 objectify.BoolElement: "bool",
48 objectify.StringElement: "str",
49
50 }
51
52 pytype2objclass = dict(( (objectclass2pytype[k], k) for k in objectclass2pytype))
53
54 xml_str = '''\
55 <obj:root xmlns:obj="objectified" xmlns:other="otherNS">
56 <obj:c1 a1="A1" a2="A2" other:a3="A3">
57 <obj:c2>0</obj:c2>
58 <obj:c2>1</obj:c2>
59 <obj:c2>2</obj:c2>
60 <other:c2>3</other:c2>
61 <c2>3</c2>
62 </obj:c1>
63 </obj:root>'''
64
66 """Test cases for lxml.objectify
67 """
68 etree = etree
69
72
83
89
93
98
105
115
120
126
134
145
149
154
161
171
176
182
190
201
203
204 value = objectify.DataElement(23, _pytype="str", _xsi="foobar",
205 attrib={"gnu": "muh", "cat": "meeow",
206 "dog": "wuff"},
207 bird="tchilp", dog="grrr")
208 self.assertEquals(value.get("gnu"), "muh")
209 self.assertEquals(value.get("cat"), "meeow")
210 self.assertEquals(value.get("dog"), "grrr")
211 self.assertEquals(value.get("bird"), "tchilp")
212
224
226
227
228 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
229 attrib={"gnu": "muh", "cat": "meeow",
230 "dog": "wuff"},
231 bird="tchilp", dog="grrr")
232 value = objectify.DataElement(arg, _pytype="NoneType")
233 self.assert_(isinstance(value, objectify.NoneElement))
234 self.assertEquals(value.get(XML_SCHEMA_NIL_ATTR), "true")
235 self.assertEquals(value.text, None)
236 self.assertEquals(value.pyval, None)
237 for attr in arg.attrib:
238
239 self.assertEquals(value.get(attr), arg.get(attr))
240
242
243
244 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
245 attrib={"gnu": "muh", "cat": "meeow",
246 "dog": "wuff"},
247 bird="tchilp", dog="grrr")
248 value = objectify.DataElement(arg, _pytype="int")
249 self.assert_(isinstance(value, objectify.IntElement))
250 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
251 for attr in arg.attrib:
252 if not attr == objectify.PYTYPE_ATTRIBUTE:
253 self.assertEquals(value.get(attr), arg.get(attr))
254
256
257
258 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
259 attrib={"gnu": "muh", "cat": "meeow",
260 "dog": "wuff"},
261 bird="tchilp", dog="grrr")
262 value = objectify.DataElement(arg, _xsi="xsd:int")
263 self.assert_(isinstance(value, objectify.IntElement))
264 self.assertEquals(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
265 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
266 for attr in arg.attrib:
267 if not attr in [objectify.PYTYPE_ATTRIBUTE,
268 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
269 self.assertEquals(value.get(attr), arg.get(attr))
270
272
273
274 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
275 attrib={"gnu": "muh", "cat": "meeow",
276 "dog": "wuff"},
277 bird="tchilp", dog="grrr")
278 value = objectify.DataElement(arg, _pytype="int", _xsi="xsd:int")
279 self.assert_(isinstance(value, objectify.IntElement))
280 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
281 self.assertEquals(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
282 for attr in arg.attrib:
283 if not attr in [objectify.PYTYPE_ATTRIBUTE,
284 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
285 self.assertEquals(value.get(attr), arg.get(attr))
286
290
294
299
304
308
312
316
321
323 root = self.XML(xml_str)
324 self.assertEquals("0", getattr(root.c1, "{objectified}c2").text)
325 self.assertEquals("3", getattr(root.c1, "{otherNS}c2").text)
326
328 root = self.XML(xml_str)
329 self.assertRaises(AttributeError, getattr, root.c1, "NOT_THERE")
330 self.assertRaises(AttributeError, getattr, root.c1, "{unknownNS}c2")
331
338
340 root = self.XML(xml_str)
341 self.assertEquals(1, len(root.c1))
342
343 new_el = self.Element("test", myattr="5")
344 root.addattr("c1", new_el)
345 self.assertEquals(2, len(root.c1))
346 self.assertEquals(None, root.c1[0].get("myattr"))
347 self.assertEquals("5", root.c1[1].get("myattr"))
348
350 root = self.XML(xml_str)
351 self.assertEquals(1, len(root.c1))
352
353 new_el = self.Element("test")
354 self.etree.SubElement(new_el, "a", myattr="A")
355 self.etree.SubElement(new_el, "a", myattr="B")
356
357 root.addattr("c1", list(new_el.a))
358 self.assertEquals(3, len(root.c1))
359 self.assertEquals(None, root.c1[0].get("myattr"))
360 self.assertEquals("A", root.c1[1].get("myattr"))
361 self.assertEquals("B", root.c1[2].get("myattr"))
362
369
371 root = self.XML(xml_str)
372 self.assertEquals("0", root.c1.c2[0].text)
373 self.assertEquals("1", root.c1.c2[1].text)
374 self.assertEquals("2", root.c1.c2[2].text)
375 self.assertRaises(IndexError, operator.getitem, root.c1.c2, 3)
376
378 root = self.XML(xml_str)
379 self.assertEquals("0", root.c1.c2[0].text)
380 self.assertEquals("0", root.c1.c2[-3].text)
381 self.assertEquals("1", root.c1.c2[-2].text)
382 self.assertEquals("2", root.c1.c2[-1].text)
383 self.assertRaises(IndexError, operator.getitem, root.c1.c2, -4)
384
386 root = self.XML(xml_str)
387 self.assertEquals(1, len(root))
388 self.assertEquals(1, len(root.c1))
389 self.assertEquals(3, len(root.c1.c2))
390
399
405
415
420
425
427 Element = self.Element
428 SubElement = self.etree.SubElement
429 root = Element("root")
430 root.c = ["c1", "c2"]
431
432 c1 = root.c[0]
433 c2 = root.c[1]
434
435 self.assertEquals([c1,c2], list(root.c))
436 self.assertEquals(["c1", "c2"],
437 [ c.text for c in root.c ])
438
439 root2 = Element("root2")
440 root2.el = [ "test", "test" ]
441 self.assertEquals(["test", "test"],
442 [ el.text for el in root2.el ])
443
444 root.c = [ root2.el, root2.el ]
445 self.assertEquals(["test", "test"],
446 [ c.text for c in root.c ])
447 self.assertEquals(["test", "test"],
448 [ el.text for el in root2.el ])
449
450 root.c[:] = [ c1, c2, c2, c1 ]
451 self.assertEquals(["c1", "c2", "c2", "c1"],
452 [ c.text for c in root.c ])
453
462
471
473
474 Element = self.Element
475 SubElement = self.etree.SubElement
476 root = Element("root")
477
478 root["text"] = "TEST"
479 self.assertEquals(["TEST"],
480 [ c.text for c in root["text"] ])
481
482 root["tail"] = "TEST"
483 self.assertEquals(["TEST"],
484 [ c.text for c in root["tail"] ])
485
486 root["pyval"] = "TEST"
487 self.assertEquals(["TEST"],
488 [ c.text for c in root["pyval"] ])
489
490 root["tag"] = "TEST"
491 self.assertEquals(["TEST"],
492 [ c.text for c in root["tag"] ])
493
501
503 XML = self.XML
504 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')
505 self.assertEquals(2, len(root.findall(".//{X}b")))
506 self.assertEquals(3, len(root.findall(".//b")))
507 self.assertEquals(2, len(root.findall("b")))
508
516
530
536
548
557
564
571
578
580 Element = self.Element
581 SubElement = self.etree.SubElement
582 root = Element("{objectified}root")
583 root.s = "test"
584
585 self.assertEquals("test" * 5, root.s * 5)
586 self.assertEquals(5 * "test", 5 * root.s)
587
588 self.assertRaises(TypeError, operator.mul, root.s, "honk")
589 self.assertRaises(TypeError, operator.mul, "honk", root.s)
590
600
605
610
615
622
627
634
639
648
657
663
672
674 pyval = 1
675 pytype = "NoneType"
676 objclass = objectify.NoneElement
677 value = objectify.DataElement(pyval, _pytype=pytype)
678 self.assert_(isinstance(value, objclass),
679 "DataElement(%s, _pytype='%s') returns %s, expected %s"
680 % (pyval, pytype, type(value), objclass))
681 self.assertEquals(value.text, None)
682 self.assertEquals(value.pyval, None)
683
685
686 pyval = 1
687 pytype = "none"
688 objclass = objectify.NoneElement
689 value = objectify.DataElement(pyval, _pytype=pytype)
690 self.assert_(isinstance(value, objclass),
691 "DataElement(%s, _pytype='%s') returns %s, expected %s"
692 % (pyval, pytype, type(value), objclass))
693 self.assertEquals(value.text, None)
694 self.assertEquals(value.pyval, None)
695
701 root = Element("{objectified}root")
702 root.myfloat = MyFloat(5.5)
703 self.assert_(isinstance(root.myfloat, objectify.FloatElement))
704 self.assertEquals(root.myfloat.get(objectify.PYTYPE_ATTRIBUTE), None)
705
707 class MyFloat(float):
708 pass
709 value = objectify.DataElement(MyFloat(5.5))
710 self.assert_(isinstance(value, objectify.FloatElement))
711 self.assertEquals(value, 5.5)
712 self.assertEquals(value.get(objectify.PYTYPE_ATTRIBUTE), None)
713
715 XML = self.XML
716 root = XML('''\
717 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
718 <b xsi:type="boolean">true</b>
719 <b xsi:type="boolean">false</b>
720 <b xsi:type="boolean">1</b>
721 <b xsi:type="boolean">0</b>
722
723 <f xsi:type="float">5</f>
724 <f xsi:type="double">5</f>
725
726 <s xsi:type="string">5</s>
727 <s xsi:type="normalizedString">5</s>
728 <s xsi:type="token">5</s>
729 <s xsi:type="language">5</s>
730 <s xsi:type="Name">5</s>
731 <s xsi:type="NCName">5</s>
732 <s xsi:type="ID">5</s>
733 <s xsi:type="IDREF">5</s>
734 <s xsi:type="ENTITY">5</s>
735 <s xsi:type="NMTOKEN">5</s>
736
737 <l xsi:type="integer">5</l>
738 <l xsi:type="nonPositiveInteger">5</l>
739 <l xsi:type="negativeInteger">5</l>
740 <l xsi:type="long">5</l>
741 <l xsi:type="nonNegativeInteger">5</l>
742 <l xsi:type="unsignedLong">5</l>
743 <l xsi:type="unsignedInt">5</l>
744 <l xsi:type="positiveInteger">5</l>
745
746 <i xsi:type="int">5</i>
747 <i xsi:type="short">5</i>
748 <i xsi:type="byte">5</i>
749 <i xsi:type="unsignedShort">5</i>
750 <i xsi:type="unsignedByte">5</i>
751
752 <n xsi:nil="true"/>
753 </root>
754 ''')
755
756 for b in root.b:
757 self.assert_(isinstance(b, objectify.BoolElement))
758 self.assertEquals(True, root.b[0])
759 self.assertEquals(False, root.b[1])
760 self.assertEquals(True, root.b[2])
761 self.assertEquals(False, root.b[3])
762
763 for f in root.f:
764 self.assert_(isinstance(f, objectify.FloatElement))
765 self.assertEquals(5, f)
766
767 for s in root.s:
768 self.assert_(isinstance(s, objectify.StringElement))
769 self.assertEquals("5", s)
770
771 for l in root.l:
772 self.assert_(isinstance(l, objectify.LongElement))
773 self.assertEquals(5L, l)
774
775 for i in root.i:
776 self.assert_(isinstance(i, objectify.IntElement))
777 self.assertEquals(5, i)
778
779 self.assert_(isinstance(root.n, objectify.NoneElement))
780 self.assertEquals(None, root.n)
781
783 XML = self.XML
784 root = XML('''\
785 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
786 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
787 <b xsi:type="xsd:boolean">true</b>
788 <b xsi:type="xsd:boolean">false</b>
789 <b xsi:type="xsd:boolean">1</b>
790 <b xsi:type="xsd:boolean">0</b>
791
792 <f xsi:type="xsd:float">5</f>
793 <f xsi:type="xsd:double">5</f>
794
795 <s xsi:type="xsd:string">5</s>
796 <s xsi:type="xsd:normalizedString">5</s>
797 <s xsi:type="xsd:token">5</s>
798 <s xsi:type="xsd:language">5</s>
799 <s xsi:type="xsd:Name">5</s>
800 <s xsi:type="xsd:NCName">5</s>
801 <s xsi:type="xsd:ID">5</s>
802 <s xsi:type="xsd:IDREF">5</s>
803 <s xsi:type="xsd:ENTITY">5</s>
804 <s xsi:type="xsd:NMTOKEN">5</s>
805
806 <l xsi:type="xsd:integer">5</l>
807 <l xsi:type="xsd:nonPositiveInteger">5</l>
808 <l xsi:type="xsd:negativeInteger">5</l>
809 <l xsi:type="xsd:long">5</l>
810 <l xsi:type="xsd:nonNegativeInteger">5</l>
811 <l xsi:type="xsd:unsignedLong">5</l>
812 <l xsi:type="xsd:unsignedInt">5</l>
813 <l xsi:type="xsd:positiveInteger">5</l>
814
815 <i xsi:type="xsd:int">5</i>
816 <i xsi:type="xsd:short">5</i>
817 <i xsi:type="xsd:byte">5</i>
818 <i xsi:type="xsd:unsignedShort">5</i>
819 <i xsi:type="xsd:unsignedByte">5</i>
820
821 <n xsi:nil="true"/>
822 </root>
823 ''')
824
825 for b in root.b:
826 self.assert_(isinstance(b, objectify.BoolElement))
827 self.assertEquals(True, root.b[0])
828 self.assertEquals(False, root.b[1])
829 self.assertEquals(True, root.b[2])
830 self.assertEquals(False, root.b[3])
831
832 for f in root.f:
833 self.assert_(isinstance(f, objectify.FloatElement))
834 self.assertEquals(5, f)
835
836 for s in root.s:
837 self.assert_(isinstance(s, objectify.StringElement))
838 self.assertEquals("5", s)
839
840 for l in root.l:
841 self.assert_(isinstance(l, objectify.LongElement))
842 self.assertEquals(5L, l)
843
844 for i in root.i:
845 self.assert_(isinstance(i, objectify.IntElement))
846 self.assertEquals(5, i)
847
848 self.assert_(isinstance(root.n, objectify.NoneElement))
849 self.assertEquals(None, root.n)
850
852 XML = self.XML
853 root = XML(u'<root><b>why</b><b>try</b></root>')
854 strs = [ str(s) for s in root.b ]
855 self.assertEquals(["why", "try"],
856 strs)
857
878
899
923
929
936
940
942 XML = self.XML
943 root = XML(u'''\
944 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
945 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
946 <b>5</b>
947 <b>test</b>
948 <c>1.1</c>
949 <c>\uF8D2</c>
950 <x>true</x>
951 <n xsi:nil="true" />
952 <n></n>
953 <b xsi:type="double">5</b>
954 <b xsi:type="float">5</b>
955 <s xsi:type="string">23</s>
956 <s py:pytype="str">42</s>
957 <f py:pytype="float">300</f>
958 <l py:pytype="long">2</l>
959 </a>
960 ''')
961 objectify.annotate(root)
962
963 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
964 for c in root.iterchildren() ]
965 self.assertEquals("int", child_types[ 0])
966 self.assertEquals("str", child_types[ 1])
967 self.assertEquals("float", child_types[ 2])
968 self.assertEquals("str", child_types[ 3])
969 self.assertEquals("bool", child_types[ 4])
970 self.assertEquals("NoneType", child_types[ 5])
971 self.assertEquals(None, child_types[ 6])
972 self.assertEquals("float", child_types[ 7])
973 self.assertEquals("float", child_types[ 8])
974 self.assertEquals("str", child_types[ 9])
975 self.assertEquals("int", child_types[10])
976 self.assertEquals("int", child_types[11])
977 self.assertEquals("int", child_types[12])
978
979 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
980
1000
1002 XML = self.XML
1003 root = XML(u'''\
1004 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1005 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1006 <b>5</b>
1007 <b>test</b>
1008 <c>1.1</c>
1009 <c>\uF8D2</c>
1010 <x>true</x>
1011 <n xsi:nil="true" />
1012 <n></n>
1013 <b xsi:type="double">5</b>
1014 <b xsi:type="float">5</b>
1015 <s xsi:type="string">23</s>
1016 <s py:pytype="str">42</s>
1017 <f py:pytype="float">300</f>
1018 <l py:pytype="long">2</l>
1019 </a>
1020 ''')
1021 objectify.annotate(root, ignore_old=False)
1022
1023 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1024 for c in root.iterchildren() ]
1025 self.assertEquals("int", child_types[ 0])
1026 self.assertEquals("str", child_types[ 1])
1027 self.assertEquals("float", child_types[ 2])
1028 self.assertEquals("str", child_types[ 3])
1029 self.assertEquals("bool", child_types[ 4])
1030 self.assertEquals("NoneType", child_types[ 5])
1031 self.assertEquals(None, child_types[ 6])
1032 self.assertEquals("float", child_types[ 7])
1033 self.assertEquals("float", child_types[ 8])
1034 self.assertEquals("str", child_types[ 9])
1035 self.assertEquals("str", child_types[10])
1036 self.assertEquals("float", child_types[11])
1037 self.assertEquals("long", child_types[12])
1038
1039 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1040
1042 XML = self.XML
1043 root = XML(u'''\
1044 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1045 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1046 <b>5</b>
1047 <b>test</b>
1048 <c>1.1</c>
1049 <c>\uF8D2</c>
1050 <x>true</x>
1051 <n xsi:nil="true" />
1052 <n></n>
1053 <b xsi:type="double">5</b>
1054 <b xsi:type="float">5</b>
1055 <s xsi:type="string">23</s>
1056 <s py:pytype="str">42</s>
1057 <f py:pytype="float">300</f>
1058 <l py:pytype="long">2</l>
1059 </a>
1060 ''')
1061 objectify.xsiannotate(root)
1062
1063 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1064 for c in root.iterchildren() ]
1065 self.assertEquals("xsd:int", child_types[ 0])
1066 self.assertEquals("xsd:string", child_types[ 1])
1067 self.assertEquals("xsd:double", child_types[ 2])
1068 self.assertEquals("xsd:string", child_types[ 3])
1069 self.assertEquals("xsd:boolean", child_types[ 4])
1070 self.assertEquals(None, child_types[ 5])
1071 self.assertEquals(None, child_types[ 6])
1072 self.assertEquals("xsd:int", child_types[ 7])
1073 self.assertEquals("xsd:int", child_types[ 8])
1074 self.assertEquals("xsd:int", child_types[ 9])
1075 self.assertEquals("xsd:string", child_types[10])
1076 self.assertEquals("xsd:double", child_types[11])
1077 self.assertEquals("xsd:integer", child_types[12])
1078
1079 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1080
1082 XML = self.XML
1083 root = XML(u'''\
1084 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1085 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1086 <b>5</b>
1087 <b>test</b>
1088 <c>1.1</c>
1089 <c>\uF8D2</c>
1090 <x>true</x>
1091 <n xsi:nil="true" />
1092 <n></n>
1093 <b xsi:type="double">5</b>
1094 <b xsi:type="float">5</b>
1095 <s xsi:type="string">23</s>
1096 <s py:pytype="str">42</s>
1097 <f py:pytype="float">300</f>
1098 <l py:pytype="long">2</l>
1099 </a>
1100 ''')
1101 objectify.xsiannotate(root, ignore_old=False)
1102
1103 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1104 for c in root.iterchildren() ]
1105 self.assertEquals("xsd:int", child_types[ 0])
1106 self.assertEquals("xsd:string", child_types[ 1])
1107 self.assertEquals("xsd:double", child_types[ 2])
1108 self.assertEquals("xsd:string", child_types[ 3])
1109 self.assertEquals("xsd:boolean", child_types[ 4])
1110 self.assertEquals(None, child_types[ 5])
1111 self.assertEquals(None, child_types[ 6])
1112 self.assertEquals("xsd:double", child_types[ 7])
1113 self.assertEquals("xsd:float", child_types[ 8])
1114 self.assertEquals("xsd:string", child_types[ 9])
1115 self.assertEquals("xsd:string", child_types[10])
1116 self.assertEquals("xsd:double", child_types[11])
1117 self.assertEquals("xsd:integer", child_types[12])
1118
1119 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1120
1122 XML = self.XML
1123 root = XML(u'''\
1124 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1125 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1126 <b>5</b>
1127 <b>test</b>
1128 <c>1.1</c>
1129 <c>\uF8D2</c>
1130 <x>true</x>
1131 <n xsi:nil="true" />
1132 <n></n>
1133 <b xsi:type="double">5</b>
1134 <b xsi:type="float">5</b>
1135 <s xsi:type="string">23</s>
1136 <s py:pytype="str">42</s>
1137 <f py:pytype="float">300</f>
1138 <l py:pytype="long">2</l>
1139 </a>
1140 ''')
1141 objectify.deannotate(root)
1142
1143 for c in root.getiterator():
1144 self.assertEquals(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1145 self.assertEquals(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1146
1147 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1148
1150 XML = self.XML
1151 root = XML(u'''\
1152 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1153 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1154 <b>5</b>
1155 <b>test</b>
1156 <c>1.1</c>
1157 <c>\uF8D2</c>
1158 <x>true</x>
1159 <n xsi:nil="true" />
1160 <n></n>
1161 <b xsi:type="double">5</b>
1162 <b xsi:type="float">5</b>
1163 <s xsi:type="string">23</s>
1164 <s py:pytype="str">42</s>
1165 <f py:pytype="float">300</f>
1166 <l py:pytype="long">2</l>
1167 </a>
1168 ''')
1169 objectify.xsiannotate(root)
1170 objectify.deannotate(root, xsi=False)
1171
1172 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1173 for c in root.iterchildren() ]
1174 self.assertEquals("xsd:int", child_types[ 0])
1175 self.assertEquals("xsd:string", child_types[ 1])
1176 self.assertEquals("xsd:double", child_types[ 2])
1177 self.assertEquals("xsd:string", child_types[ 3])
1178 self.assertEquals("xsd:boolean", child_types[ 4])
1179 self.assertEquals(None, child_types[ 5])
1180 self.assertEquals(None, child_types[ 6])
1181 self.assertEquals("xsd:int", child_types[ 7])
1182 self.assertEquals("xsd:int", child_types[ 8])
1183 self.assertEquals("xsd:int", child_types[ 9])
1184 self.assertEquals("xsd:string", child_types[10])
1185 self.assertEquals("xsd:double", child_types[11])
1186 self.assertEquals("xsd:integer", child_types[12])
1187
1188 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1189
1190 for c in root.getiterator():
1191 self.assertEquals(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1192
1194 XML = self.XML
1195 root = XML(u'''\
1196 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1197 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1198 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1199 <b>5</b>
1200 <b>test</b>
1201 <c>1.1</c>
1202 <c>\uF8D2</c>
1203 <x>true</x>
1204 <n xsi:nil="true" />
1205 <n></n>
1206 <b xsi:type="xsd:double">5</b>
1207 <b xsi:type="xsd:float">5</b>
1208 <s xsi:type="xsd:string">23</s>
1209 <s py:pytype="str">42</s>
1210 <f py:pytype="float">300</f>
1211 <l py:pytype="long">2</l>
1212 </a>
1213 ''')
1214 objectify.annotate(root)
1215 objectify.deannotate(root, pytype=False)
1216
1217 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1218 for c in root.iterchildren() ]
1219 self.assertEquals("int", child_types[ 0])
1220 self.assertEquals("str", child_types[ 1])
1221 self.assertEquals("float", child_types[ 2])
1222 self.assertEquals("str", child_types[ 3])
1223 self.assertEquals("bool", child_types[ 4])
1224 self.assertEquals("NoneType", child_types[ 5])
1225 self.assertEquals(None, child_types[ 6])
1226 self.assertEquals("float", child_types[ 7])
1227 self.assertEquals("float", child_types[ 8])
1228 self.assertEquals("str", child_types[ 9])
1229 self.assertEquals("int", child_types[10])
1230 self.assertEquals("int", child_types[11])
1231 self.assertEquals("int", child_types[12])
1232
1233 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1234
1235 for c in root.getiterator():
1236 self.assertEquals(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1237
1239 XML = self.XML
1240 root = XML(u'''\
1241 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1242 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1243 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1244 <b xsi:type="xsd:int">5</b>
1245 <b xsi:type="xsd:string">test</b>
1246 <c xsi:type="xsd:float">1.1</c>
1247 <c xsi:type="xsd:string">\uF8D2</c>
1248 <x xsi:type="xsd:boolean">true</x>
1249 <n xsi:nil="true" />
1250 <n></n>
1251 <b xsi:type="xsd:double">5</b>
1252 <b xsi:type="xsd:float">5</b>
1253 <s xsi:type="xsd:string">23</s>
1254 <s xsi:type="xsd:string">42</s>
1255 <f xsi:type="xsd:float">300</f>
1256 <l xsi:type="xsd:long">2</l>
1257 </a>
1258 ''')
1259 objectify.annotate(root)
1260 objectify.deannotate(root, xsi=False)
1261
1262 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1263 for c in root.iterchildren() ]
1264 self.assertEquals("xsd:int", child_types[ 0])
1265 self.assertEquals("xsd:string", child_types[ 1])
1266 self.assertEquals("xsd:float", child_types[ 2])
1267 self.assertEquals("xsd:string", child_types[ 3])
1268 self.assertEquals("xsd:boolean", child_types[ 4])
1269 self.assertEquals(None, child_types[ 5])
1270 self.assertEquals(None, child_types[ 6])
1271 self.assertEquals("xsd:double", child_types[ 7])
1272 self.assertEquals("xsd:float", child_types[ 8])
1273 self.assertEquals("xsd:string", child_types[ 9])
1274 self.assertEquals("xsd:string", child_types[10])
1275 self.assertEquals("xsd:float", child_types[11])
1276 self.assertEquals("xsd:long", child_types[12])
1277
1278 self.assertEquals("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1279
1280 for c in root.getiterator():
1281 self.assertEquals(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1282
1284 XML = self.XML
1285
1286 xml = u'''\
1287 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1288 <b>5</b>
1289 <b>test</b>
1290 <c>1.1</c>
1291 <c>\uF8D2</c>
1292 <x>true</x>
1293 <n xsi:nil="true" />
1294 <n></n>
1295 <b xsi:type="double">5</b>
1296 </a>
1297 '''
1298
1299 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1300 objectify.setPytypeAttributeTag("{TEST}test")
1301
1302 root = XML(xml)
1303 objectify.annotate(root)
1304
1305 attribs = root.xpath("//@py:%s" % pytype_name, {"py" : pytype_ns})
1306 self.assertEquals(0, len(attribs))
1307 attribs = root.xpath("//@py:test", {"py" : "TEST"})
1308 self.assertEquals(7, len(attribs))
1309
1310 objectify.setPytypeAttributeTag()
1311 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1312
1313 self.assertNotEqual("test", pytype_ns.lower())
1314 self.assertNotEqual("test", pytype_name.lower())
1315
1316 root = XML(xml)
1317 attribs = root.xpath("//@py:%s" % pytype_name, {"py" : pytype_ns})
1318 self.assertEquals(0, len(attribs))
1319
1320 objectify.annotate(root)
1321 attribs = root.xpath("//@py:%s" % pytype_name, {"py" : pytype_ns})
1322 self.assertEquals(7, len(attribs))
1323
1333
1334 def checkMyType(s):
1335 return True
1336
1337 pytype = objectify.PyType("mytype", checkMyType, NewType)
1338 pytype.register()
1339 self.assert_(pytype in objectify.getRegisteredTypes())
1340 pytype.unregister()
1341
1342 pytype.register(before = [objectify.getRegisteredTypes()[0].name])
1343 self.assertEquals(pytype, objectify.getRegisteredTypes()[0])
1344 pytype.unregister()
1345
1346 pytype.register(after = [objectify.getRegisteredTypes()[0].name])
1347 self.assertNotEqual(pytype, objectify.getRegisteredTypes()[0])
1348 pytype.unregister()
1349
1350 self.assertRaises(ValueError, pytype.register,
1351 before = [objectify.getRegisteredTypes()[0].name],
1352 after = [objectify.getRegisteredTypes()[1].name])
1353
1354 finally:
1355 for pytype in objectify.getRegisteredTypes():
1356 pytype.unregister()
1357 for pytype in orig_types:
1358 pytype.register()
1359
1365
1371
1377
1385
1404
1409
1414
1419
1424
1444
1446 root = self.XML(xml_str)
1447 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[0]'] )
1448 self.assertEquals(root.c1.c2.text, path(root).text)
1449
1450 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[2]'] )
1451 self.assertEquals(root.c1.c2[2].text, path(root).text)
1452
1453 path = objectify.ObjectPath( ['root', 'c1', 'c2[2]'] )
1454 self.assertEquals(root.c1.c2[2].text, path(root).text)
1455
1456 path = objectify.ObjectPath( ['root', 'c1', 'c2[-1]'] )
1457 self.assertEquals(root.c1.c2[-1].text, path(root).text)
1458
1459 path = objectify.ObjectPath( ['root', 'c1', 'c2[-3]'] )
1460 self.assertEquals(root.c1.c2[-3].text, path(root).text)
1461
1463 self.assertRaises(ValueError, objectify.ObjectPath,
1464 "root.c1[0].c2[-1-2]")
1465 self.assertRaises(ValueError, objectify.ObjectPath,
1466 ['root', 'c1[0]', 'c2[-1-2]'])
1467
1468 self.assertRaises(ValueError, objectify.ObjectPath,
1469 "root[2].c1.c2")
1470 self.assertRaises(ValueError, objectify.ObjectPath,
1471 ['root[2]', 'c1', 'c2'])
1472
1473 self.assertRaises(ValueError, objectify.ObjectPath,
1474 [])
1475 self.assertRaises(ValueError, objectify.ObjectPath,
1476 ['', '', ''])
1477
1479 root = self.XML(xml_str)
1480 path = objectify.ObjectPath("root.c1[9999].c2")
1481 self.assertRaises(AttributeError, path, root)
1482
1483 path = objectify.ObjectPath("root.c1[0].c2[9999]")
1484 self.assertRaises(AttributeError, path, root)
1485
1486 path = objectify.ObjectPath(".c1[9999].c2[0]")
1487 self.assertRaises(AttributeError, path, root)
1488
1489 path = objectify.ObjectPath("root.c1[-2].c2")
1490 self.assertRaises(AttributeError, path, root)
1491
1492 path = objectify.ObjectPath("root.c1[0].c2[-4]")
1493 self.assertRaises(AttributeError, path, root)
1494
1508
1510 root = self.XML(xml_str)
1511 path = objectify.ObjectPath( ['{objectified}root', 'c1', 'c2'] )
1512 self.assertEquals(root.c1.c2.text, path.find(root).text)
1513 path = objectify.ObjectPath( ['{objectified}root', '{objectified}c1', 'c2'] )
1514 self.assertEquals(root.c1.c2.text, path.find(root).text)
1515 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2'] )
1516 self.assertEquals(root.c1.c2.text, path.find(root).text)
1517 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2[2]'] )
1518 self.assertEquals(root.c1.c2[2].text, path.find(root).text)
1519 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2'] )
1520 self.assertEquals(root.c1.c2.text, path.find(root).text)
1521 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2[2]'] )
1522 self.assertEquals(root.c1.c2[2].text, path.find(root).text)
1523 path = objectify.ObjectPath( ['root', 'c1', '{otherNS}c2'] )
1524 self.assertEquals(getattr(root.c1, '{otherNS}c2').text,
1525 path.find(root).text)
1526
1539
1554
1566
1580
1582 root = self.XML(xml_str)
1583 path = objectify.ObjectPath( "root.c1.c99" )
1584 self.assertRaises(AttributeError, path.find, root)
1585
1586 new_el = self.Element("{objectified}test")
1587 new_el.a = ["TEST1", "TEST2"]
1588 new_el.a[0].set("myattr", "ATTR1")
1589 new_el.a[1].set("myattr", "ATTR2")
1590
1591 path.setattr(root, list(new_el.a))
1592
1593 self.assertEquals(2, len(root.c1.c99))
1594 self.assertEquals("ATTR1", root.c1.c99[0].get("myattr"))
1595 self.assertEquals("TEST1", root.c1.c99[0].text)
1596 self.assertEquals("ATTR2", root.c1.c99[1].get("myattr"))
1597 self.assertEquals("TEST2", root.c1.c99[1].text)
1598 self.assertEquals("TEST1", path(root).text)
1599
1608
1622
1634
1648
1663
1665 root = self.XML(xml_str)
1666 self.assertEquals(
1667 ['{objectified}root', '{objectified}root.c1',
1668 '{objectified}root.c1.c2',
1669 '{objectified}root.c1.c2[1]', '{objectified}root.c1.c2[2]',
1670 '{objectified}root.c1.{otherNS}c2', '{objectified}root.c1.{}c2'],
1671 root.descendantpaths())
1672
1674 root = self.XML(xml_str)
1675 self.assertEquals(
1676 ['{objectified}c1', '{objectified}c1.c2',
1677 '{objectified}c1.c2[1]', '{objectified}c1.c2[2]',
1678 '{objectified}c1.{otherNS}c2', '{objectified}c1.{}c2'],
1679 root.c1.descendantpaths())
1680
1682 root = self.XML(xml_str)
1683 self.assertEquals(
1684 ['root.{objectified}c1', 'root.{objectified}c1.c2',
1685 'root.{objectified}c1.c2[1]', 'root.{objectified}c1.c2[2]',
1686 'root.{objectified}c1.{otherNS}c2',
1687 'root.{objectified}c1.{}c2'],
1688 root.c1.descendantpaths('root'))
1689
1701
1702
1703
1708
1713
1718
1723
1728
1733
1738
1743
1748
1750 E = objectify.E
1751 DataElement = objectify.DataElement
1752 root = E.root("text", E.sub(E.subsub()), "tail", DataElement(1),
1753 DataElement(2.0))
1754 self.assert_(isinstance(root, objectify.ObjectifiedElement))
1755 self.assertEquals(root.text, "text")
1756 self.assert_(isinstance(root.sub, objectify.ObjectifiedElement))
1757 self.assertEquals(root.sub.tail, "tail")
1758 self.assert_(isinstance(root.sub.subsub, objectify.StringElement))
1759 self.assertEquals(len(root.value), 2)
1760 self.assert_(isinstance(root.value[0], objectify.IntElement))
1761 self.assert_(isinstance(root.value[1], objectify.FloatElement))
1762
1764 suite = unittest.TestSuite()
1765 suite.addTests([unittest.makeSuite(ObjectifyTestCase)])
1766 suite.addTests(
1767 [doctest.DocFileSuite('../../../doc/objectify.txt')])
1768 return suite
1769
1770 if __name__ == '__main__':
1771 print 'to test use test.py %s' % __file__
1772