1
2
3 """
4 Tests specific to the lxml.objectify API
5 """
6
7
8 import unittest, operator, sys, os.path
9
10 this_dir = os.path.dirname(__file__)
11 if this_dir not in sys.path:
12 sys.path.insert(0, this_dir)
13
14 from common_imports import etree, HelperTestCase, fileInTestDir
15 from common_imports import SillyFileLike, canonicalize, doctest, make_doctest
16 from common_imports import _bytes, _str, StringIO, BytesIO
17
18 from lxml import objectify
19
20 PYTYPE_NAMESPACE = "http://codespeak.net/lxml/objectify/pytype"
21 XML_SCHEMA_NS = "http://www.w3.org/2001/XMLSchema"
22 XML_SCHEMA_INSTANCE_NS = "http://www.w3.org/2001/XMLSchema-instance"
23 XML_SCHEMA_INSTANCE_TYPE_ATTR = "{%s}type" % XML_SCHEMA_INSTANCE_NS
24 XML_SCHEMA_NIL_ATTR = "{%s}nil" % XML_SCHEMA_INSTANCE_NS
25 TREE_PYTYPE = "TREE"
26 DEFAULT_NSMAP = { "py" : PYTYPE_NAMESPACE,
27 "xsi" : XML_SCHEMA_INSTANCE_NS,
28 "xsd" : XML_SCHEMA_NS}
29
30 objectclass2xsitype = {
31
32 objectify.IntElement: ("int", "short", "byte", "unsignedShort",
33 "unsignedByte", "integer", "nonPositiveInteger",
34 "negativeInteger", "long", "nonNegativeInteger",
35 "unsignedLong", "unsignedInt", "positiveInteger",),
36 objectify.FloatElement: ("float", "double"),
37 objectify.BoolElement: ("boolean",),
38 objectify.StringElement: ("string", "normalizedString", "token", "language",
39 "Name", "NCName", "ID", "IDREF", "ENTITY",
40 "NMTOKEN", ),
41
42 }
43
44 xsitype2objclass = dict([ (v, k) for k in objectclass2xsitype
45 for v in objectclass2xsitype[k] ])
46
47 objectclass2pytype = {
48
49 objectify.IntElement: "int",
50 objectify.FloatElement: "float",
51 objectify.BoolElement: "bool",
52 objectify.StringElement: "str",
53
54 }
55
56 pytype2objclass = dict([ (objectclass2pytype[k], k)
57 for k in objectclass2pytype])
58
59 xml_str = '''\
60 <obj:root xmlns:obj="objectified" xmlns:other="otherNS">
61 <obj:c1 a1="A1" a2="A2" other:a3="A3">
62 <obj:c2>0</obj:c2>
63 <obj:c2>1</obj:c2>
64 <obj:c2>2</obj:c2>
65 <other:c2>3</other:c2>
66 <c2>4</c2>
67 </obj:c1>
68 </obj:root>'''
69
71 """Test cases for lxml.objectify
72 """
73 etree = etree
74
77
91
105
106
110
115
122
132
137
143
151
162
166
171
178
188
193
199
207
218
220
221 value = objectify.ObjectifiedDataElement('test', 'toast')
222 self.assertEqual(value.text, 'testtoast')
223
228
230
231 value = objectify.DataElement(23, _pytype="str", _xsi="foobar",
232 attrib={"gnu": "muh", "cat": "meeow",
233 "dog": "wuff"},
234 bird="tchilp", dog="grrr")
235 self.assertEqual(value.get("gnu"), "muh")
236 self.assertEqual(value.get("cat"), "meeow")
237 self.assertEqual(value.get("dog"), "grrr")
238 self.assertEqual(value.get("bird"), "tchilp")
239
251
253
254
255 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
256 attrib={"gnu": "muh", "cat": "meeow",
257 "dog": "wuff"},
258 bird="tchilp", dog="grrr")
259 value = objectify.DataElement(arg, _pytype="NoneType")
260 self.assertTrue(isinstance(value, objectify.NoneElement))
261 self.assertEqual(value.get(XML_SCHEMA_NIL_ATTR), "true")
262 self.assertEqual(value.text, None)
263 self.assertEqual(value.pyval, None)
264 for attr in arg.attrib:
265
266 self.assertEqual(value.get(attr), arg.get(attr))
267
269
270
271 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
272 attrib={"gnu": "muh", "cat": "meeow",
273 "dog": "wuff"},
274 bird="tchilp", dog="grrr")
275 value = objectify.DataElement(arg, _pytype="int")
276 self.assertTrue(isinstance(value, objectify.IntElement))
277 self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
278 for attr in arg.attrib:
279 if not attr == objectify.PYTYPE_ATTRIBUTE:
280 self.assertEqual(value.get(attr), arg.get(attr))
281
283
284
285 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
286 attrib={"gnu": "muh", "cat": "meeow",
287 "dog": "wuff"},
288 bird="tchilp", dog="grrr")
289 value = objectify.DataElement(arg, _xsi="xsd:int")
290 self.assertTrue(isinstance(value, objectify.IntElement))
291 self.assertEqual(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
292 self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
293 for attr in arg.attrib:
294 if not attr in [objectify.PYTYPE_ATTRIBUTE,
295 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
296 self.assertEqual(value.get(attr), arg.get(attr))
297
299
300
301 arg = objectify.DataElement(23, _pytype="str", _xsi="foobar",
302 attrib={"gnu": "muh", "cat": "meeow",
303 "dog": "wuff"},
304 bird="tchilp", dog="grrr")
305 value = objectify.DataElement(arg, _pytype="int", _xsi="xsd:int")
306 self.assertTrue(isinstance(value, objectify.IntElement))
307 self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), "int")
308 self.assertEqual(value.get(XML_SCHEMA_INSTANCE_TYPE_ATTR), "xsd:int")
309 for attr in arg.attrib:
310 if not attr in [objectify.PYTYPE_ATTRIBUTE,
311 XML_SCHEMA_INSTANCE_TYPE_ATTR]:
312 self.assertEqual(value.get(attr), arg.get(attr))
313
317
321
326
331
338
342
346
350
352 root = self.XML("""
353 <root>
354 <foo:x xmlns:foo="/foo/bar">1</foo:x>
355 <x>2</x>
356 </root>
357 """)
358 self.assertEqual(2, root.x)
359
364
366 root = self.XML(xml_str)
367 self.assertEqual("0", getattr(root.c1, "{objectified}c2").text)
368 self.assertEqual("3", getattr(root.c1, "{otherNS}c2").text)
369
371 root = self.XML(xml_str)
372 self.assertRaises(AttributeError, getattr, root.c1, "NOT_THERE")
373 self.assertRaises(AttributeError, getattr, root.c1, "{unknownNS}c2")
374
379
381 for val in [
382 2, 2**32, 1.2, "Won't get fooled again",
383 _str("W\xf6n't get f\xf6\xf6led \xe4g\xe4in", 'ISO-8859-1'), True,
384 False, None]:
385 root = self.Element('root')
386 attrname = 'val'
387 setattr(root, attrname, val)
388 result = getattr(root, attrname)
389 self.assertEqual(val, result)
390 self.assertEqual(type(val), type(result.pyval))
391
398
405
407 root = self.XML(xml_str)
408 self.assertEqual(1, len(root.c1))
409
410 new_el = self.Element("test", myattr="5")
411 root.addattr("c1", new_el)
412 self.assertEqual(2, len(root.c1))
413 self.assertEqual(None, root.c1[0].get("myattr"))
414 self.assertEqual("5", root.c1[1].get("myattr"))
415
417 root = self.XML(xml_str)
418 self.assertEqual(1, len(root.c1))
419
420 new_el = self.Element("test")
421 self.etree.SubElement(new_el, "a", myattr="A")
422 self.etree.SubElement(new_el, "a", myattr="B")
423
424 root.addattr("c1", list(new_el.a))
425 self.assertEqual(3, len(root.c1))
426 self.assertEqual(None, root.c1[0].get("myattr"))
427 self.assertEqual("A", root.c1[1].get("myattr"))
428 self.assertEqual("B", root.c1[2].get("myattr"))
429
436
438 root = self.XML(xml_str)
439 self.assertEqual("0", root.c1.c2[0].text)
440 self.assertEqual("1", root.c1.c2[1].text)
441 self.assertEqual("2", root.c1.c2[2].text)
442 self.assertRaises(IndexError, operator.getitem, root.c1.c2, 3)
443
445 root = self.XML(xml_str)
446 self.assertEqual("0", root.c1.c2[0].text)
447 self.assertEqual("0", root.c1.c2[-3].text)
448 self.assertEqual("1", root.c1.c2[-2].text)
449 self.assertEqual("2", root.c1.c2[-1].text)
450 self.assertRaises(IndexError, operator.getitem, root.c1.c2, -4)
451
453 root = self.XML(xml_str)
454 self.assertEqual(1, len(root))
455 self.assertEqual(1, len(root.c1))
456 self.assertEqual(3, len(root.c1.c2))
457
466
472
482
487
492
493
494
496 root = self.XML("<root><c>c1</c><c>c2</c></root>")
497 self.assertEqual(["c1", "c2"],
498 [ c.text for c in root.c[:] ])
499
501 root = self.XML("<root><c>c1</c><c>c2</c><c>c3</c><c>c4</c></root>")
502 test_list = ["c1", "c2", "c3", "c4"]
503
504 self.assertEqual(test_list,
505 [ c.text for c in root.c[:] ])
506 self.assertEqual(test_list[1:2],
507 [ c.text for c in root.c[1:2] ])
508 self.assertEqual(test_list[-3:-1],
509 [ c.text for c in root.c[-3:-1] ])
510 self.assertEqual(test_list[-3:3],
511 [ c.text for c in root.c[-3:3] ])
512 self.assertEqual(test_list[-3000:3],
513 [ c.text for c in root.c[-3000:3] ])
514 self.assertEqual(test_list[-3:3000],
515 [ c.text for c in root.c[-3:3000] ])
516
518 root = self.XML("<root><c>c1</c><c>c2</c><c>c3</c><c>c4</c></root>")
519 test_list = ["c1", "c2", "c3", "c4"]
520
521 self.assertEqual(test_list,
522 [ c.text for c in root.c[:] ])
523 self.assertEqual(test_list[2:1:-1],
524 [ c.text for c in root.c[2:1:-1] ])
525 self.assertEqual(test_list[-1:-3:-1],
526 [ c.text for c in root.c[-1:-3:-1] ])
527 self.assertEqual(test_list[2:-3:-1],
528 [ c.text for c in root.c[2:-3:-1] ])
529 self.assertEqual(test_list[2:-3000:-1],
530 [ c.text for c in root.c[2:-3000:-1] ])
531
532
533
545
547 Element = self.Element
548 root = Element("root")
549 root.c = ["c1", "c2"]
550
551 c1 = root.c[0]
552 c2 = root.c[1]
553
554 self.assertEqual([c1,c2], list(root.c))
555 self.assertEqual(["c1", "c2"],
556 [ c.text for c in root.c ])
557
558 root2 = Element("root2")
559 root2.el = [ "test", "test" ]
560 self.assertEqual(["test", "test"],
561 [ el.text for el in root2.el ])
562
563 root.c = [ root2.el, root2.el ]
564 self.assertEqual(["test", "test"],
565 [ c.text for c in root.c ])
566 self.assertEqual(["test", "test"],
567 [ el.text for el in root2.el ])
568
569 root.c[:] = [ c1, c2, c2, c1 ]
570 self.assertEqual(["c1", "c2", "c2", "c1"],
571 [ c.text for c in root.c ])
572
574 Element = self.Element
575 root = Element("root")
576 l = ["c1", "c2", "c3", "c4"]
577 root.c = l
578
579 self.assertEqual(["c1", "c2", "c3", "c4"],
580 [ c.text for c in root.c ])
581 self.assertEqual(l,
582 [ c.text for c in root.c ])
583
584 new_slice = ["cA", "cB"]
585 l[1:2] = new_slice
586 root.c[1:2] = new_slice
587
588 self.assertEqual(["c1", "cA", "cB", "c3", "c4"], l)
589 self.assertEqual(["c1", "cA", "cB", "c3", "c4"],
590 [ c.text for c in root.c ])
591 self.assertEqual(l,
592 [ c.text for c in root.c ])
593
595 Element = self.Element
596 root = Element("root")
597 l = ["c1", "c2", "c3", "c4"]
598 root.c = l
599
600 self.assertEqual(["c1", "c2", "c3", "c4"],
601 [ c.text for c in root.c ])
602 self.assertEqual(l,
603 [ c.text for c in root.c ])
604
605 new_slice = ["cA", "cB"]
606 l[1:1] = new_slice
607 root.c[1:1] = new_slice
608
609 self.assertEqual(["c1", "cA", "cB", "c2", "c3", "c4"], l)
610 self.assertEqual(["c1", "cA", "cB", "c2", "c3", "c4"],
611 [ c.text for c in root.c ])
612 self.assertEqual(l,
613 [ c.text for c in root.c ])
614
616 Element = self.Element
617 root = Element("root")
618 l = ["c1", "c2", "c3", "c4"]
619 root.c = l
620
621 self.assertEqual(["c1", "c2", "c3", "c4"],
622 [ c.text for c in root.c ])
623 self.assertEqual(l,
624 [ c.text for c in root.c ])
625
626 new_slice = ["cA", "cB"]
627 l[-2:-2] = new_slice
628 root.c[-2:-2] = new_slice
629
630 self.assertEqual(["c1", "c2", "cA", "cB", "c3", "c4"], l)
631 self.assertEqual(["c1", "c2", "cA", "cB", "c3", "c4"],
632 [ c.text for c in root.c ])
633 self.assertEqual(l,
634 [ c.text for c in root.c ])
635
643
645 Element = self.Element
646 root = Element("root")
647 l = ["c1", "c2", "c3", "c4"]
648 root.c = l
649
650 self.assertEqual(["c1", "c2", "c3", "c4"],
651 [ c.text for c in root.c ])
652 self.assertEqual(l,
653 [ c.text for c in root.c ])
654
655 new_slice = ["cA", "cB", "cC"]
656 self.assertRaises(
657 ValueError, operator.setitem,
658 l, slice(1,2,-1), new_slice)
659 self.assertRaises(
660 ValueError, operator.setitem,
661 root.c, slice(1,2,-1), new_slice)
662
664 Element = self.Element
665 root = Element("root")
666 l = ["c1", "c2", "c3", "c4"]
667 root.c = l
668
669 self.assertEqual(["c1", "c2", "c3", "c4"],
670 [ c.text for c in root.c ])
671 self.assertEqual(l,
672 [ c.text for c in root.c ])
673
674 new_slice = ["cA", "cB"]
675 l[-1:1:-1] = new_slice
676 root.c[-1:1:-1] = new_slice
677
678 self.assertEqual(["c1", "c2", "cB", "cA"], l)
679 self.assertEqual(["c1", "c2", "cB", "cA"],
680 [ c.text for c in root.c ])
681 self.assertEqual(l,
682 [ c.text for c in root.c ])
683
685 Element = self.Element
686 root = Element("root")
687 l = ["c1", "c2", "c3", "c4"]
688 root.c = l
689
690 self.assertEqual(["c1", "c2", "c3", "c4"],
691 [ c.text for c in root.c ])
692 self.assertEqual(l,
693 [ c.text for c in root.c ])
694
695 new_slice = ["cA", "cB"]
696 l[-1:-4:-2] = new_slice
697 root.c[-1:-4:-2] = new_slice
698
699 self.assertEqual(["c1", "cB", "c3", "cA"], l)
700 self.assertEqual(["c1", "cB", "c3", "cA"],
701 [ c.text for c in root.c ])
702 self.assertEqual(l,
703 [ c.text for c in root.c ])
704
705
706
714
722
724
725 Element = self.Element
726 root = Element("root")
727
728 root["text"] = "TEST"
729 self.assertEqual(["TEST"],
730 [ c.text for c in root["text"] ])
731
732 root["tail"] = "TEST"
733 self.assertEqual(["TEST"],
734 [ c.text for c in root["tail"] ])
735
736 root["pyval"] = "TEST"
737 self.assertEqual(["TEST"],
738 [ c.text for c in root["pyval"] ])
739
740 root["tag"] = "TEST"
741 self.assertEqual(["TEST"],
742 [ c.text for c in root["tag"] ])
743
751
753 XML = self.XML
754 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')
755 self.assertEqual(2, len(root.findall(".//{X}b")))
756 self.assertEqual(3, len(root.findall(".//b")))
757 self.assertEqual(2, len(root.findall("b")))
758
766
781
787
789 Element = self.Element
790 SubElement = self.etree.SubElement
791 root = Element("{objectified}root")
792 root.bool = True
793 self.assertEqual(root.bool, True)
794 self.assertEqual(root.bool + root.bool, True + True)
795 self.assertEqual(True + root.bool, True + root.bool)
796 self.assertEqual(root.bool * root.bool, True * True)
797 self.assertEqual(int(root.bool), int(True))
798 self.assertEqual(hash(root.bool), hash(True))
799 self.assertEqual(complex(root.bool), complex(True))
800 self.assertTrue(isinstance(root.bool, objectify.BoolElement))
801
802 root.bool = False
803 self.assertEqual(root.bool, False)
804 self.assertEqual(root.bool + root.bool, False + False)
805 self.assertEqual(False + root.bool, False + root.bool)
806 self.assertEqual(root.bool * root.bool, False * False)
807 self.assertEqual(int(root.bool), int(False))
808 self.assertEqual(hash(root.bool), hash(False))
809 self.assertEqual(complex(root.bool), complex(False))
810 self.assertTrue(isinstance(root.bool, objectify.BoolElement))
811
820
827
834
841
853
863
884
889
894
899
904
913
918
923
928
935
942
949
961
971
976
981
986
993
998
1002
1009
1014
1018
1027
1036
1042
1051
1053 pyval = 1
1054 pytype = "NoneType"
1055 objclass = objectify.NoneElement
1056 value = objectify.DataElement(pyval, _pytype=pytype)
1057 self.assertTrue(isinstance(value, objclass),
1058 "DataElement(%s, _pytype='%s') returns %s, expected %s"
1059 % (pyval, pytype, type(value), objclass))
1060 self.assertEqual(value.text, None)
1061 self.assertEqual(value.pyval, None)
1062
1064
1065 pyval = 1
1066 pytype = "none"
1067 objclass = objectify.NoneElement
1068 value = objectify.DataElement(pyval, _pytype=pytype)
1069 self.assertTrue(isinstance(value, objclass),
1070 "DataElement(%s, _pytype='%s') returns %s, expected %s"
1071 % (pyval, pytype, type(value), objclass))
1072 self.assertEqual(value.text, None)
1073 self.assertEqual(value.pyval, None)
1074
1080 root = Element("{objectified}root")
1081 root.myfloat = MyFloat(5.5)
1082 self.assertTrue(isinstance(root.myfloat, objectify.FloatElement))
1083 self.assertEqual(root.myfloat.get(objectify.PYTYPE_ATTRIBUTE), None)
1084
1086 class MyFloat(float):
1087 pass
1088 value = objectify.DataElement(MyFloat(5.5))
1089 self.assertTrue(isinstance(value, objectify.FloatElement))
1090 self.assertEqual(value, 5.5)
1091 self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), None)
1092
1094 XML = self.XML
1095 root = XML('''\
1096 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1097 <b xsi:type="boolean">true</b>
1098 <b xsi:type="boolean">false</b>
1099 <b xsi:type="boolean">1</b>
1100 <b xsi:type="boolean">0</b>
1101
1102 <f xsi:type="float">5</f>
1103 <f xsi:type="double">5</f>
1104
1105 <s xsi:type="string">5</s>
1106 <s xsi:type="normalizedString">5</s>
1107 <s xsi:type="token">5</s>
1108 <s xsi:type="language">5</s>
1109 <s xsi:type="Name">5</s>
1110 <s xsi:type="NCName">5</s>
1111 <s xsi:type="ID">5</s>
1112 <s xsi:type="IDREF">5</s>
1113 <s xsi:type="ENTITY">5</s>
1114 <s xsi:type="NMTOKEN">5</s>
1115
1116 <l xsi:type="integer">5</l>
1117 <l xsi:type="nonPositiveInteger">5</l>
1118 <l xsi:type="negativeInteger">5</l>
1119 <l xsi:type="long">5</l>
1120 <l xsi:type="nonNegativeInteger">5</l>
1121 <l xsi:type="unsignedLong">5</l>
1122 <l xsi:type="unsignedInt">5</l>
1123 <l xsi:type="positiveInteger">5</l>
1124
1125 <i xsi:type="int">5</i>
1126 <i xsi:type="short">5</i>
1127 <i xsi:type="byte">5</i>
1128 <i xsi:type="unsignedShort">5</i>
1129 <i xsi:type="unsignedByte">5</i>
1130
1131 <n xsi:nil="true"/>
1132 </root>
1133 ''')
1134
1135 for b in root.b:
1136 self.assertTrue(isinstance(b, objectify.BoolElement))
1137 self.assertEqual(True, root.b[0])
1138 self.assertEqual(False, root.b[1])
1139 self.assertEqual(True, root.b[2])
1140 self.assertEqual(False, root.b[3])
1141
1142 for f in root.f:
1143 self.assertTrue(isinstance(f, objectify.FloatElement))
1144 self.assertEqual(5, f)
1145
1146 for s in root.s:
1147 self.assertTrue(isinstance(s, objectify.StringElement))
1148 self.assertEqual("5", s)
1149
1150 for i in root.i:
1151 self.assertTrue(isinstance(i, objectify.IntElement))
1152 self.assertEqual(5, i)
1153
1154 for l in root.l:
1155 self.assertTrue(isinstance(l, objectify.IntElement))
1156 self.assertEqual(5, i)
1157
1158 self.assertTrue(isinstance(root.n, objectify.NoneElement))
1159 self.assertEqual(None, root.n)
1160
1162 XML = self.XML
1163 root = XML('''\
1164 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1165 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1166 <b xsi:type="xsd:boolean">true</b>
1167 <b xsi:type="xsd:boolean">false</b>
1168 <b xsi:type="xsd:boolean">1</b>
1169 <b xsi:type="xsd:boolean">0</b>
1170
1171 <f xsi:type="xsd:float">5</f>
1172 <f xsi:type="xsd:double">5</f>
1173
1174 <s xsi:type="xsd:string">5</s>
1175 <s xsi:type="xsd:normalizedString">5</s>
1176 <s xsi:type="xsd:token">5</s>
1177 <s xsi:type="xsd:language">5</s>
1178 <s xsi:type="xsd:Name">5</s>
1179 <s xsi:type="xsd:NCName">5</s>
1180 <s xsi:type="xsd:ID">5</s>
1181 <s xsi:type="xsd:IDREF">5</s>
1182 <s xsi:type="xsd:ENTITY">5</s>
1183 <s xsi:type="xsd:NMTOKEN">5</s>
1184
1185 <l xsi:type="xsd:integer">5</l>
1186 <l xsi:type="xsd:nonPositiveInteger">5</l>
1187 <l xsi:type="xsd:negativeInteger">5</l>
1188 <l xsi:type="xsd:long">5</l>
1189 <l xsi:type="xsd:nonNegativeInteger">5</l>
1190 <l xsi:type="xsd:unsignedLong">5</l>
1191 <l xsi:type="xsd:unsignedInt">5</l>
1192 <l xsi:type="xsd:positiveInteger">5</l>
1193
1194 <i xsi:type="xsd:int">5</i>
1195 <i xsi:type="xsd:short">5</i>
1196 <i xsi:type="xsd:byte">5</i>
1197 <i xsi:type="xsd:unsignedShort">5</i>
1198 <i xsi:type="xsd:unsignedByte">5</i>
1199
1200 <n xsi:nil="true"/>
1201 </root>
1202 ''')
1203
1204 for b in root.b:
1205 self.assertTrue(isinstance(b, objectify.BoolElement))
1206 self.assertEqual(True, root.b[0])
1207 self.assertEqual(False, root.b[1])
1208 self.assertEqual(True, root.b[2])
1209 self.assertEqual(False, root.b[3])
1210
1211 for f in root.f:
1212 self.assertTrue(isinstance(f, objectify.FloatElement))
1213 self.assertEqual(5, f)
1214
1215 for s in root.s:
1216 self.assertTrue(isinstance(s, objectify.StringElement))
1217 self.assertEqual("5", s)
1218
1219 for i in root.i:
1220 self.assertTrue(isinstance(i, objectify.IntElement))
1221 self.assertEqual(5, i)
1222
1223 for l in root.l:
1224 self.assertTrue(isinstance(l, objectify.IntElement))
1225 self.assertEqual(5, l)
1226
1227 self.assertTrue(isinstance(root.n, objectify.NoneElement))
1228 self.assertEqual(None, root.n)
1229
1231 XML = self.XML
1232 root = XML(_bytes('<root><b>why</b><b>try</b></root>'))
1233 strs = [ str(s) for s in root.b ]
1234 self.assertEqual(["why", "try"],
1235 strs)
1236
1263
1283
1284
1285
1309
1311 XML = self.XML
1312 root = XML(_bytes("""
1313 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1314 <b xsi:nil="true"></b><b xsi:nil="true"/>
1315 </root>"""))
1316 self.assertTrue(root.b[0] == root.b[1])
1317 self.assertFalse(root.b[0])
1318 self.assertEqual(root.b[0], None)
1319 self.assertEqual(None, root.b[0])
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1335
1342
1346
1348 XML = self.XML
1349 root = XML(_bytes('''\
1350 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1351 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1352 <b>5</b>
1353 <b>test</b>
1354 <c>1.1</c>
1355 <c>\uF8D2</c>
1356 <x>true</x>
1357 <n xsi:nil="true" />
1358 <n></n>
1359 <b xsi:type="double">5</b>
1360 <b xsi:type="float">5</b>
1361 <s xsi:type="string">23</s>
1362 <s py:pytype="str">42</s>
1363 <f py:pytype="float">300</f>
1364 <l py:pytype="long">2</l>
1365 <t py:pytype="TREE"></t>
1366 </a>
1367 '''))
1368 objectify.annotate(root)
1369
1370 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1371 for c in root.iterchildren() ]
1372 self.assertEqual("int", child_types[ 0])
1373 self.assertEqual("str", child_types[ 1])
1374 self.assertEqual("float", child_types[ 2])
1375 self.assertEqual("str", child_types[ 3])
1376 self.assertEqual("bool", child_types[ 4])
1377 self.assertEqual("NoneType", child_types[ 5])
1378 self.assertEqual(None, child_types[ 6])
1379 self.assertEqual("float", child_types[ 7])
1380 self.assertEqual("float", child_types[ 8])
1381 self.assertEqual("str", child_types[ 9])
1382 self.assertEqual("int", child_types[10])
1383 self.assertEqual("int", child_types[11])
1384 self.assertEqual("int", child_types[12])
1385 self.assertEqual(None, child_types[13])
1386
1387 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1388
1408
1410 XML = self.XML
1411 root = XML(_bytes('''\
1412 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1413 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1414 <b>5</b>
1415 <b>test</b>
1416 <c>1.1</c>
1417 <c>\uF8D2</c>
1418 <x>true</x>
1419 <n xsi:nil="true" />
1420 <n></n>
1421 <b xsi:type="double">5</b>
1422 <b xsi:type="float">5</b>
1423 <s xsi:type="string">23</s>
1424 <s py:pytype="str">42</s>
1425 <f py:pytype="float">300</f>
1426 <l py:pytype="long">2</l>
1427 <t py:pytype="TREE"></t>
1428 </a>
1429 '''))
1430 objectify.annotate(root, ignore_old=False)
1431
1432 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1433 for c in root.iterchildren() ]
1434 self.assertEqual("int", child_types[ 0])
1435 self.assertEqual("str", child_types[ 1])
1436 self.assertEqual("float", child_types[ 2])
1437 self.assertEqual("str", child_types[ 3])
1438 self.assertEqual("bool", child_types[ 4])
1439 self.assertEqual("NoneType", child_types[ 5])
1440 self.assertEqual(None, child_types[ 6])
1441 self.assertEqual("float", child_types[ 7])
1442 self.assertEqual("float", child_types[ 8])
1443 self.assertEqual("str", child_types[ 9])
1444 self.assertEqual("str", child_types[10])
1445 self.assertEqual("float", child_types[11])
1446 self.assertEqual("int", child_types[12])
1447 self.assertEqual(TREE_PYTYPE, child_types[13])
1448
1449 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1450
1452 XML = self.XML
1453 root = XML(_bytes('''\
1454 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1455 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1456 <b>5</b>
1457 <b>test</b>
1458 <c>1.1</c>
1459 <c>\uF8D2</c>
1460 <x>true</x>
1461 <n xsi:nil="true" />
1462 <n></n>
1463 <b xsi:type="double">5</b>
1464 <b xsi:type="float">5</b>
1465 <s xsi:type="string">23</s>
1466 <s py:pytype="str">42</s>
1467 <f py:pytype="float">300</f>
1468 <l py:pytype="long">2</l>
1469 <t py:pytype="TREE"></t>
1470 </a>
1471 '''))
1472 objectify.annotate(root, ignore_old=False, ignore_xsi=False,
1473 annotate_xsi=1, annotate_pytype=1)
1474
1475
1476 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1477 for c in root.iterchildren() ]
1478 self.assertEqual("int", child_types[ 0])
1479 self.assertEqual("str", child_types[ 1])
1480 self.assertEqual("float", child_types[ 2])
1481 self.assertEqual("str", child_types[ 3])
1482 self.assertEqual("bool", child_types[ 4])
1483 self.assertEqual("NoneType", child_types[ 5])
1484 self.assertEqual(None, child_types[ 6])
1485 self.assertEqual("float", child_types[ 7])
1486 self.assertEqual("float", child_types[ 8])
1487 self.assertEqual("str", child_types[ 9])
1488 self.assertEqual("str", child_types[10])
1489 self.assertEqual("float", child_types[11])
1490 self.assertEqual("int", child_types[12])
1491 self.assertEqual(TREE_PYTYPE, child_types[13])
1492
1493 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1494
1495 child_xsitypes = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1496 for c in root.iterchildren() ]
1497
1498
1499 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1500 for c in root.iterchildren() ]
1501 self.assertEqual("xsd:integer", child_types[ 0])
1502 self.assertEqual("xsd:string", child_types[ 1])
1503 self.assertEqual("xsd:double", child_types[ 2])
1504 self.assertEqual("xsd:string", child_types[ 3])
1505 self.assertEqual("xsd:boolean", child_types[ 4])
1506 self.assertEqual(None, child_types[ 5])
1507 self.assertEqual(None, child_types[ 6])
1508 self.assertEqual("xsd:double", child_types[ 7])
1509 self.assertEqual("xsd:float", child_types[ 8])
1510 self.assertEqual("xsd:string", child_types[ 9])
1511 self.assertEqual("xsd:string", child_types[10])
1512 self.assertEqual("xsd:double", child_types[11])
1513 self.assertEqual("xsd:integer", child_types[12])
1514 self.assertEqual(None, child_types[13])
1515
1516 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1517
1519 XML = self.XML
1520 root = XML(_bytes('''\
1521 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1522 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1523 <b>5</b>
1524 <b>test</b>
1525 <c>1.1</c>
1526 <c>\uF8D2</c>
1527 <x>true</x>
1528 <n xsi:nil="true" />
1529 <n></n>
1530 <b xsi:type="double">5</b>
1531 <b xsi:type="float">5</b>
1532 <s xsi:type="string">23</s>
1533 <s py:pytype="str">42</s>
1534 <f py:pytype="float">300</f>
1535 <l py:pytype="long">2</l>
1536 <t py:pytype="TREE"></t>
1537 </a>
1538 '''))
1539 objectify.xsiannotate(root, ignore_old=False)
1540
1541 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1542 for c in root.iterchildren() ]
1543 self.assertEqual("xsd:integer", child_types[ 0])
1544 self.assertEqual("xsd:string", child_types[ 1])
1545 self.assertEqual("xsd:double", child_types[ 2])
1546 self.assertEqual("xsd:string", child_types[ 3])
1547 self.assertEqual("xsd:boolean", child_types[ 4])
1548 self.assertEqual(None, child_types[ 5])
1549 self.assertEqual(None, child_types[ 6])
1550 self.assertEqual("xsd:double", child_types[ 7])
1551 self.assertEqual("xsd:float", child_types[ 8])
1552 self.assertEqual("xsd:string", child_types[ 9])
1553 self.assertEqual("xsd:string", child_types[10])
1554 self.assertEqual("xsd:double", child_types[11])
1555 self.assertEqual("xsd:integer", child_types[12])
1556 self.assertEqual(None, child_types[13])
1557
1559 XML = self.XML
1560 root = XML(_bytes('''\
1561 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1562 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1563 <b>5</b>
1564 <b>test</b>
1565 <c>1.1</c>
1566 <c>\uF8D2</c>
1567 <x>true</x>
1568 <n xsi:nil="true" />
1569 <n></n>
1570 <b xsi:type="double">5</b>
1571 <b xsi:type="float">5</b>
1572 <s xsi:type="string">23</s>
1573 <s py:pytype="str">42</s>
1574 <f py:pytype="float">300</f>
1575 <l py:pytype="long">2</l>
1576 <t py:pytype="TREE"></t>
1577 </a>
1578 '''))
1579 objectify.pyannotate(root, ignore_old=True)
1580
1581 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1582 for c in root.iterchildren() ]
1583 self.assertEqual("int", child_types[ 0])
1584 self.assertEqual("str", child_types[ 1])
1585 self.assertEqual("float", child_types[ 2])
1586 self.assertEqual("str", child_types[ 3])
1587 self.assertEqual("bool", child_types[ 4])
1588 self.assertEqual("NoneType", child_types[ 5])
1589 self.assertEqual(None, child_types[ 6])
1590 self.assertEqual("float", child_types[ 7])
1591 self.assertEqual("float", child_types[ 8])
1592 self.assertEqual("str", child_types[ 9])
1593 self.assertEqual("int", child_types[10])
1594 self.assertEqual("int", child_types[11])
1595 self.assertEqual("int", child_types[12])
1596 self.assertEqual(None, child_types[13])
1597
1598 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1599
1619
1621 XML = self.XML
1622 root = XML('''\
1623 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1624 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1625 <b>5</b>
1626 <b>test</b>
1627 <c>1.1</c>
1628 <c>\uF8D2</c>
1629 <x>true</x>
1630 <n xsi:nil="true" />
1631 <n></n>
1632 <b xsi:type="double">5</b>
1633 <b xsi:type="float">5</b>
1634 <s xsi:type="string">23</s>
1635 <s py:pytype="str">42</s>
1636 <f py:pytype="float">300</f>
1637 <l py:pytype="long">2</l>
1638 <t py:pytype="TREE"></t>
1639 </a>
1640 ''')
1641 objectify.pyannotate(root)
1642
1643 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1644 for c in root.iterchildren() ]
1645 self.assertEqual("int", child_types[ 0])
1646 self.assertEqual("str", child_types[ 1])
1647 self.assertEqual("float", child_types[ 2])
1648 self.assertEqual("str", child_types[ 3])
1649 self.assertEqual("bool", child_types[ 4])
1650 self.assertEqual("NoneType", child_types[ 5])
1651 self.assertEqual(None, child_types[ 6])
1652 self.assertEqual("float", child_types[ 7])
1653 self.assertEqual("float", child_types[ 8])
1654 self.assertEqual("str", child_types[ 9])
1655 self.assertEqual("str", child_types[10])
1656 self.assertEqual("float", child_types[11])
1657 self.assertEqual("int", child_types[12])
1658 self.assertEqual(TREE_PYTYPE, child_types[13])
1659
1660 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1661
1663 XML = self.XML
1664 root = XML(_bytes('''\
1665 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1666 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1667 <b>5</b>
1668 <b>test</b>
1669 <c>1.1</c>
1670 <c>\uF8D2</c>
1671 <x>true</x>
1672 <n xsi:nil="true" />
1673 <n></n>
1674 <b xsi:type="double">5</b>
1675 <b xsi:type="float">5</b>
1676 <s xsi:type="string">23</s>
1677 <s py:pytype="str">42</s>
1678 <f py:pytype="float">300</f>
1679 <l py:pytype="long">2</l>
1680 <t py:pytype="TREE"></t>
1681 </a>
1682 '''))
1683 objectify.xsiannotate(root, ignore_old=True)
1684
1685 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1686 for c in root.iterchildren() ]
1687 self.assertEqual("xsd:integer", child_types[ 0])
1688 self.assertEqual("xsd:string", child_types[ 1])
1689 self.assertEqual("xsd:double", child_types[ 2])
1690 self.assertEqual("xsd:string", child_types[ 3])
1691 self.assertEqual("xsd:boolean", child_types[ 4])
1692 self.assertEqual(None, child_types[ 5])
1693 self.assertEqual(None, child_types[ 6])
1694 self.assertEqual("xsd:integer", child_types[ 7])
1695 self.assertEqual("xsd:integer", child_types[ 8])
1696 self.assertEqual("xsd:integer", child_types[ 9])
1697 self.assertEqual("xsd:string", child_types[10])
1698 self.assertEqual("xsd:double", child_types[11])
1699 self.assertEqual("xsd:integer", child_types[12])
1700 self.assertEqual(None, child_types[13])
1701
1702 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1703
1705 XML = self.XML
1706 root = XML(_bytes('''\
1707 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1708 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1709 <b>5</b>
1710 <b>test</b>
1711 <c>1.1</c>
1712 <c>\uF8D2</c>
1713 <x>true</x>
1714 <n xsi:nil="true" />
1715 <n></n>
1716 <b xsi:type="double">5</b>
1717 <b xsi:type="float">5</b>
1718 <s xsi:type="string">23</s>
1719 <s py:pytype="str">42</s>
1720 <f py:pytype="float">300</f>
1721 <l py:pytype="long">2</l>
1722 <t py:pytype="TREE"></t>
1723 </a>
1724 '''))
1725 objectify.deannotate(root)
1726
1727 for c in root.getiterator():
1728 self.assertEqual(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1729 self.assertEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1730
1731 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1732
1734 XML = self.XML
1735 root = XML(_bytes('''\
1736 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1737 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1738 <b>5</b>
1739 <b>test</b>
1740 <c>1.1</c>
1741 <c>\uF8D2</c>
1742 <x>true</x>
1743 <n xsi:nil="true" />
1744 <n></n>
1745 <b xsi:type="double">5</b>
1746 <b xsi:type="float">5</b>
1747 <s xsi:type="string">23</s>
1748 <s py:pytype="str">42</s>
1749 <f py:pytype="float">300</f>
1750 <l py:pytype="long">2</l>
1751 <t py:pytype="TREE"></t>
1752 </a>
1753 '''))
1754 objectify.annotate(
1755 root, ignore_old=False, ignore_xsi=False, annotate_xsi=True,
1756 empty_pytype='str', empty_type='string')
1757 objectify.deannotate(root, pytype=False, xsi=False, xsi_nil=True)
1758
1759 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1760 for c in root.iterchildren() ]
1761 self.assertEqual("xsd:integer", child_types[ 0])
1762 self.assertEqual("xsd:string", child_types[ 1])
1763 self.assertEqual("xsd:double", child_types[ 2])
1764 self.assertEqual("xsd:string", child_types[ 3])
1765 self.assertEqual("xsd:boolean", child_types[ 4])
1766 self.assertEqual(None, child_types[ 5])
1767 self.assertEqual("xsd:string", child_types[ 6])
1768 self.assertEqual("xsd:double", child_types[ 7])
1769 self.assertEqual("xsd:float", child_types[ 8])
1770 self.assertEqual("xsd:string", child_types[ 9])
1771 self.assertEqual("xsd:string", child_types[10])
1772 self.assertEqual("xsd:double", child_types[11])
1773 self.assertEqual("xsd:integer", child_types[12])
1774 self.assertEqual(None, child_types[13])
1775
1776 self.assertEqual(None, root.n.get(XML_SCHEMA_NIL_ATTR))
1777
1778 for c in root.iterchildren():
1779 self.assertNotEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1780
1781 if (c.get(objectify.PYTYPE_ATTRIBUTE) not in [TREE_PYTYPE,
1782 "NoneType"]):
1783 self.assertNotEqual(
1784 None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1785
1787 XML = self.XML
1788 root = XML(_bytes('''\
1789 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1790 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1791 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1792 <b>5</b>
1793 <b>test</b>
1794 <c>1.1</c>
1795 <c>\uF8D2</c>
1796 <x>true</x>
1797 <n xsi:nil="true" />
1798 <n></n>
1799 <b xsi:type="xsd:double">5</b>
1800 <b xsi:type="xsd:float">5</b>
1801 <s xsi:type="xsd:string">23</s>
1802 <s py:pytype="str">42</s>
1803 <f py:pytype="float">300</f>
1804 <l py:pytype="long">2</l>
1805 <t py:pytype="TREE"></t>
1806 </a>
1807 '''))
1808 objectify.annotate(root)
1809 objectify.deannotate(root, pytype=False)
1810
1811 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1812 for c in root.iterchildren() ]
1813 self.assertEqual("int", child_types[ 0])
1814 self.assertEqual("str", child_types[ 1])
1815 self.assertEqual("float", child_types[ 2])
1816 self.assertEqual("str", child_types[ 3])
1817 self.assertEqual("bool", child_types[ 4])
1818 self.assertEqual("NoneType", child_types[ 5])
1819 self.assertEqual(None, child_types[ 6])
1820 self.assertEqual("float", child_types[ 7])
1821 self.assertEqual("float", child_types[ 8])
1822 self.assertEqual("str", child_types[ 9])
1823 self.assertEqual("int", child_types[10])
1824 self.assertEqual("int", child_types[11])
1825 self.assertEqual("int", child_types[12])
1826 self.assertEqual(None, child_types[13])
1827
1828 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1829
1830 for c in root.getiterator():
1831 self.assertEqual(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1832
1834 XML = self.XML
1835 root = XML(_bytes('''\
1836 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1837 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1838 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1839 <b xsi:type="xsd:int">5</b>
1840 <b xsi:type="xsd:string">test</b>
1841 <c xsi:type="xsd:float">1.1</c>
1842 <c xsi:type="xsd:string">\uF8D2</c>
1843 <x xsi:type="xsd:boolean">true</x>
1844 <n xsi:nil="true" />
1845 <n></n>
1846 <b xsi:type="xsd:double">5</b>
1847 <b xsi:type="xsd:float">5</b>
1848 <s xsi:type="xsd:string">23</s>
1849 <s xsi:type="xsd:string">42</s>
1850 <f xsi:type="xsd:float">300</f>
1851 <l xsi:type="xsd:long">2</l>
1852 <t py:pytype="TREE"></t>
1853 </a>
1854 '''))
1855 objectify.annotate(root)
1856 objectify.deannotate(root, xsi=False)
1857
1858 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1859 for c in root.iterchildren() ]
1860 self.assertEqual("xsd:int", child_types[ 0])
1861 self.assertEqual("xsd:string", child_types[ 1])
1862 self.assertEqual("xsd:float", child_types[ 2])
1863 self.assertEqual("xsd:string", child_types[ 3])
1864 self.assertEqual("xsd:boolean", child_types[ 4])
1865 self.assertEqual(None, child_types[ 5])
1866 self.assertEqual(None, child_types[ 6])
1867 self.assertEqual("xsd:double", child_types[ 7])
1868 self.assertEqual("xsd:float", child_types[ 8])
1869 self.assertEqual("xsd:string", child_types[ 9])
1870 self.assertEqual("xsd:string", child_types[10])
1871 self.assertEqual("xsd:float", child_types[11])
1872 self.assertEqual("xsd:long", child_types[12])
1873 self.assertEqual(None, child_types[13])
1874
1875 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1876
1877 for c in root.getiterator():
1878 self.assertEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1879
1881 XML = self.XML
1882
1883 xml = _bytes('''\
1884 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1885 <b>5</b>
1886 <b>test</b>
1887 <c>1.1</c>
1888 <c>\uF8D2</c>
1889 <x>true</x>
1890 <n xsi:nil="true" />
1891 <n></n>
1892 <b xsi:type="double">5</b>
1893 </a>
1894 ''')
1895
1896 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1897 objectify.set_pytype_attribute_tag("{TEST}test")
1898
1899 root = XML(xml)
1900 objectify.annotate(root)
1901
1902 attribs = root.xpath("//@py:%s" % pytype_name,
1903 namespaces={"py" : pytype_ns})
1904 self.assertEqual(0, len(attribs))
1905 attribs = root.xpath("//@py:test",
1906 namespaces={"py" : "TEST"})
1907 self.assertEqual(7, len(attribs))
1908
1909 objectify.set_pytype_attribute_tag()
1910 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1911
1912 self.assertNotEqual("test", pytype_ns.lower())
1913 self.assertNotEqual("test", pytype_name.lower())
1914
1915 root = XML(xml)
1916 attribs = root.xpath("//@py:%s" % pytype_name,
1917 namespaces={"py" : pytype_ns})
1918 self.assertEqual(0, len(attribs))
1919
1920 objectify.annotate(root)
1921 attribs = root.xpath("//@py:%s" % pytype_name,
1922 namespaces={"py" : pytype_ns})
1923 self.assertEqual(7, len(attribs))
1924
1932
1933 def checkMyType(s):
1934 return True
1935
1936 pytype = objectify.PyType("mytype", checkMyType, NewType)
1937 self.assertTrue(pytype not in objectify.getRegisteredTypes())
1938 pytype.register()
1939 self.assertTrue(pytype in objectify.getRegisteredTypes())
1940 pytype.unregister()
1941 self.assertTrue(pytype not in objectify.getRegisteredTypes())
1942
1943 pytype.register(before = [objectify.getRegisteredTypes()[0].name])
1944 self.assertEqual(pytype, objectify.getRegisteredTypes()[0])
1945 pytype.unregister()
1946
1947 pytype.register(after = [objectify.getRegisteredTypes()[0].name])
1948 self.assertNotEqual(pytype, objectify.getRegisteredTypes()[0])
1949 pytype.unregister()
1950
1951 self.assertRaises(ValueError, pytype.register,
1952 before = [objectify.getRegisteredTypes()[0].name],
1953 after = [objectify.getRegisteredTypes()[1].name])
1954
1956 from datetime import datetime
1957 def parse_date(value):
1958 if len(value) != 14:
1959 raise ValueError(value)
1960 Y = int(value[0:4])
1961 M = int(value[4:6])
1962 D = int(value[6:8])
1963 h = int(value[8:10])
1964 m = int(value[10:12])
1965 s = int(value[12:14])
1966 return datetime(Y, M, D, h, m, s)
1967
1968 def stringify_date(date):
1969 return date.strftime("%Y%m%d%H%M%S")
1970
1971 class DatetimeElement(objectify.ObjectifiedDataElement):
1972 def pyval(self):
1973 return parse_date(self.text)
1974 pyval = property(pyval)
1975
1976 datetime_type = objectify.PyType(
1977 "datetime", parse_date, DatetimeElement, stringify_date)
1978 datetime_type.xmlSchemaTypes = "dateTime"
1979 datetime_type.register()
1980
1981 NAMESPACE = "http://foo.net/xmlns"
1982 NAMESPACE_MAP = {'ns': NAMESPACE}
1983
1984 r = objectify.Element("{%s}root" % NAMESPACE, nsmap=NAMESPACE_MAP)
1985 time = datetime.now()
1986 r.date = time
1987
1988 self.assertTrue(isinstance(r.date, DatetimeElement))
1989 self.assertTrue(isinstance(r.date.pyval, datetime))
1990
1991 self.assertEqual(r.date.pyval, parse_date(stringify_date(time)))
1992 self.assertEqual(r.date.text, stringify_date(time))
1993
1994 r.date = objectify.E.date(time)
1995
1996 self.assertTrue(isinstance(r.date, DatetimeElement))
1997 self.assertTrue(isinstance(r.date.pyval, datetime))
1998
1999 self.assertEqual(r.date.pyval, parse_date(stringify_date(time)))
2000 self.assertEqual(r.date.text, stringify_date(time))
2001
2002 date = objectify.DataElement(time)
2003
2004 self.assertTrue(isinstance(date, DatetimeElement))
2005 self.assertTrue(isinstance(date.pyval, datetime))
2006
2007 self.assertEqual(date.pyval, parse_date(stringify_date(time)))
2008 self.assertEqual(date.text, stringify_date(time))
2009
2015
2021
2026
2035
2042
2050
2053
2056
2075
2080
2085
2090
2095
2115
2117 root = self.XML(xml_str)
2118 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[0]'] )
2119 self.assertEqual(root.c1.c2.text, path(root).text)
2120
2121 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[2]'] )
2122 self.assertEqual(root.c1.c2[2].text, path(root).text)
2123
2124 path = objectify.ObjectPath( ['root', 'c1', 'c2[2]'] )
2125 self.assertEqual(root.c1.c2[2].text, path(root).text)
2126
2127 path = objectify.ObjectPath( ['root', 'c1', 'c2[-1]'] )
2128 self.assertEqual(root.c1.c2[-1].text, path(root).text)
2129
2130 path = objectify.ObjectPath( ['root', 'c1', 'c2[-3]'] )
2131 self.assertEqual(root.c1.c2[-3].text, path(root).text)
2132
2134 self.assertRaises(ValueError, objectify.ObjectPath,
2135 "root.c1[0].c2[-1-2]")
2136 self.assertRaises(ValueError, objectify.ObjectPath,
2137 ['root', 'c1[0]', 'c2[-1-2]'])
2138
2139 self.assertRaises(ValueError, objectify.ObjectPath,
2140 "root[2].c1.c2")
2141 self.assertRaises(ValueError, objectify.ObjectPath,
2142 ['root[2]', 'c1', 'c2'])
2143
2144 self.assertRaises(ValueError, objectify.ObjectPath,
2145 [])
2146 self.assertRaises(ValueError, objectify.ObjectPath,
2147 ['', '', ''])
2148
2150 root = self.XML(xml_str)
2151 path = objectify.ObjectPath("root.c1[9999].c2")
2152 self.assertRaises(AttributeError, path, root)
2153
2154 path = objectify.ObjectPath("root.c1[0].c2[9999]")
2155 self.assertRaises(AttributeError, path, root)
2156
2157 path = objectify.ObjectPath(".c1[9999].c2[0]")
2158 self.assertRaises(AttributeError, path, root)
2159
2160 path = objectify.ObjectPath("root.c1[-2].c2")
2161 self.assertRaises(AttributeError, path, root)
2162
2163 path = objectify.ObjectPath("root.c1[0].c2[-4]")
2164 self.assertRaises(AttributeError, path, root)
2165
2179
2181 root = self.XML(xml_str)
2182 path = objectify.ObjectPath( ['{objectified}root', 'c1', 'c2'] )
2183 self.assertEqual(root.c1.c2.text, path.find(root).text)
2184 path = objectify.ObjectPath( ['{objectified}root', '{objectified}c1', 'c2'] )
2185 self.assertEqual(root.c1.c2.text, path.find(root).text)
2186 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2'] )
2187 self.assertEqual(root.c1.c2.text, path.find(root).text)
2188 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2[2]'] )
2189 self.assertEqual(root.c1.c2[2].text, path.find(root).text)
2190 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2'] )
2191 self.assertEqual(root.c1.c2.text, path.find(root).text)
2192 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2[2]'] )
2193 self.assertEqual(root.c1.c2[2].text, path.find(root).text)
2194 path = objectify.ObjectPath( ['root', 'c1', '{otherNS}c2'] )
2195 self.assertEqual(getattr(root.c1, '{otherNS}c2').text,
2196 path.find(root).text)
2197
2210
2225
2237
2251
2253 root = self.XML(xml_str)
2254 path = objectify.ObjectPath( "root.c1.c99" )
2255 self.assertRaises(AttributeError, path.find, root)
2256
2257 new_el = self.Element("{objectified}test")
2258 new_el.a = ["TEST1", "TEST2"]
2259 new_el.a[0].set("myattr", "ATTR1")
2260 new_el.a[1].set("myattr", "ATTR2")
2261
2262 path.setattr(root, list(new_el.a))
2263
2264 self.assertEqual(2, len(root.c1.c99))
2265 self.assertEqual("ATTR1", root.c1.c99[0].get("myattr"))
2266 self.assertEqual("TEST1", root.c1.c99[0].text)
2267 self.assertEqual("ATTR2", root.c1.c99[1].get("myattr"))
2268 self.assertEqual("TEST2", root.c1.c99[1].text)
2269 self.assertEqual("TEST1", path(root).text)
2270
2279
2293
2305
2319
2334
2336 root = self.XML(xml_str)
2337 self.assertEqual(
2338 ['{objectified}root', '{objectified}root.c1',
2339 '{objectified}root.c1.c2',
2340 '{objectified}root.c1.c2[1]', '{objectified}root.c1.c2[2]',
2341 '{objectified}root.c1.{otherNS}c2', '{objectified}root.c1.{}c2'],
2342 root.descendantpaths())
2343
2345 root = self.XML(xml_str)
2346 self.assertEqual(
2347 ['{objectified}c1', '{objectified}c1.c2',
2348 '{objectified}c1.c2[1]', '{objectified}c1.c2[2]',
2349 '{objectified}c1.{otherNS}c2', '{objectified}c1.{}c2'],
2350 root.c1.descendantpaths())
2351
2353 root = self.XML(xml_str)
2354 self.assertEqual(
2355 ['root.{objectified}c1', 'root.{objectified}c1.c2',
2356 'root.{objectified}c1.c2[1]', 'root.{objectified}c1.c2[2]',
2357 'root.{objectified}c1.{otherNS}c2',
2358 'root.{objectified}c1.{}c2'],
2359 root.c1.descendantpaths('root'))
2360
2372
2385
2389
2393
2397
2403
2408
2410 import pickle
2411 if isinstance(stringOrElt, (etree._Element, etree._ElementTree)):
2412 elt = stringOrElt
2413 else:
2414 elt = self.XML(stringOrElt)
2415 out = BytesIO()
2416 pickle.dump(elt, out)
2417
2418 new_elt = pickle.loads(out.getvalue())
2419 self.assertEqual(
2420 etree.tostring(new_elt),
2421 etree.tostring(elt))
2422
2423
2424
2429
2434
2439
2444
2449
2454
2459
2464
2466 E = objectify.E
2467 DataElement = objectify.DataElement
2468 root = E.root("text", E.sub(E.subsub()), "tail", DataElement(1),
2469 DataElement(2.0))
2470 self.assertTrue(isinstance(root, objectify.ObjectifiedElement))
2471 self.assertEqual(root.text, "text")
2472 self.assertTrue(isinstance(root.sub, objectify.ObjectifiedElement))
2473 self.assertEqual(root.sub.tail, "tail")
2474 self.assertTrue(isinstance(root.sub.subsub, objectify.StringElement))
2475 self.assertEqual(len(root.value), 2)
2476 self.assertTrue(isinstance(root.value[0], objectify.IntElement))
2477 self.assertTrue(isinstance(root.value[1], objectify.FloatElement))
2478
2485
2486 attr = Attribute()
2487 self.assertEqual(attr.text, None)
2488 self.assertEqual(attr.get("datatype"), "TYPE")
2489 self.assertEqual(attr.get("range"), "0.,1.")
2490
2495
2502
2507
2513
2515 root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
2516 self.assertEqual(root.base, "http://no/such/url")
2517 self.assertEqual(
2518 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2519 root.base = "https://secret/url"
2520 self.assertEqual(root.base, "https://secret/url")
2521 self.assertEqual(
2522 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2523 "https://secret/url")
2524
2526 root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
2527 self.assertEqual(root.base, "http://no/such/url")
2528 self.assertEqual(
2529 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2530 root.set('{http://www.w3.org/XML/1998/namespace}base',
2531 "https://secret/url")
2532 self.assertEqual(root.base, "https://secret/url")
2533 self.assertEqual(
2534 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2535 "https://secret/url")
2536
2538 XML = self.XML
2539
2540 xml = _bytes('''\
2541 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
2542 <i>5</i>
2543 <i>-5</i>
2544 <l>4294967296</l>
2545 <l>-4294967296</l>
2546 <f>1.1</f>
2547 <b>true</b>
2548 <b>false</b>
2549 <s>Strange things happen, where strings collide</s>
2550 <s>True</s>
2551 <s>False</s>
2552 <s>t</s>
2553 <s>f</s>
2554 <s></s>
2555 <s>None</s>
2556 <n xsi:nil="true" />
2557 </root>
2558 ''')
2559 root = XML(xml)
2560
2561 for i in root.i:
2562 self.assertTrue(isinstance(i, objectify.IntElement))
2563 for l in root.l:
2564 self.assertTrue(isinstance(l, objectify.IntElement))
2565 for f in root.f:
2566 self.assertTrue(isinstance(f, objectify.FloatElement))
2567 for b in root.b:
2568 self.assertTrue(isinstance(b, objectify.BoolElement))
2569 self.assertEqual(True, root.b[0])
2570 self.assertEqual(False, root.b[1])
2571 for s in root.s:
2572 self.assertTrue(isinstance(s, objectify.StringElement))
2573 self.assertTrue(isinstance(root.n, objectify.NoneElement))
2574 self.assertEqual(None, root.n)
2575
2577 suite = unittest.TestSuite()
2578 suite.addTests([unittest.makeSuite(ObjectifyTestCase)])
2579 suite.addTests(doctest.DocTestSuite(objectify))
2580 if sys.version_info >= (2,4):
2581 suite.addTests(
2582 [make_doctest('../../../doc/objectify.txt')])
2583 return suite
2584
2585 if __name__ == '__main__':
2586 print('to test use test.py %s' % __file__)
2587