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 self.assertEqual(root, root[0])
444 self.assertRaises(IndexError, operator.getitem, root, 1)
445
446 c1 = root.c1
447 del root.c1
448 self.assertEqual(c1, c1[0])
449 self.assertRaises(IndexError, operator.getitem, c1, 1)
450
452 root = self.XML(xml_str)
453 self.assertEqual("0", root.c1.c2[0].text)
454 self.assertEqual("0", root.c1.c2[-3].text)
455 self.assertEqual("1", root.c1.c2[-2].text)
456 self.assertEqual("2", root.c1.c2[-1].text)
457 self.assertRaises(IndexError, operator.getitem, root.c1.c2, -4)
458 self.assertEqual(root, root[-1])
459 self.assertRaises(IndexError, operator.getitem, root, -2)
460
461 c1 = root.c1
462 del root.c1
463 self.assertEqual(c1, c1[-1])
464 self.assertRaises(IndexError, operator.getitem, c1, -2)
465
467 root = self.XML(xml_str)
468 self.assertEqual(1, len(root))
469 self.assertEqual(1, len(root.c1))
470 self.assertEqual(3, len(root.c1.c2))
471
480
486
496
501
506
507
508
510 root = self.XML("<root><c>c1</c><c>c2</c></root>")
511 self.assertEqual(["c1", "c2"],
512 [ c.text for c in root.c[:] ])
513
515 root = self.XML("<root><c>c1</c><c>c2</c><c>c3</c><c>c4</c></root>")
516 test_list = ["c1", "c2", "c3", "c4"]
517
518 self.assertEqual(test_list,
519 [ c.text for c in root.c[:] ])
520 self.assertEqual(test_list[1:2],
521 [ c.text for c in root.c[1:2] ])
522 self.assertEqual(test_list[-3:-1],
523 [ c.text for c in root.c[-3:-1] ])
524 self.assertEqual(test_list[-3:3],
525 [ c.text for c in root.c[-3:3] ])
526 self.assertEqual(test_list[-3000:3],
527 [ c.text for c in root.c[-3000:3] ])
528 self.assertEqual(test_list[-3:3000],
529 [ c.text for c in root.c[-3:3000] ])
530
532 root = self.XML("<root><c>c1</c><c>c2</c><c>c3</c><c>c4</c></root>")
533 test_list = ["c1", "c2", "c3", "c4"]
534
535 self.assertEqual(test_list,
536 [ c.text for c in root.c[:] ])
537 self.assertEqual(test_list[2:1:-1],
538 [ c.text for c in root.c[2:1:-1] ])
539 self.assertEqual(test_list[-1:-3:-1],
540 [ c.text for c in root.c[-1:-3:-1] ])
541 self.assertEqual(test_list[2:-3:-1],
542 [ c.text for c in root.c[2:-3:-1] ])
543 self.assertEqual(test_list[2:-3000:-1],
544 [ c.text for c in root.c[2:-3000:-1] ])
545
546
547
559
561 Element = self.Element
562 root = Element("root")
563 root.c = ["c1", "c2"]
564
565 c1 = root.c[0]
566 c2 = root.c[1]
567
568 self.assertEqual([c1,c2], list(root.c))
569 self.assertEqual(["c1", "c2"],
570 [ c.text for c in root.c ])
571
572 root2 = Element("root2")
573 root2.el = [ "test", "test" ]
574 self.assertEqual(["test", "test"],
575 [ el.text for el in root2.el ])
576
577 root.c = [ root2.el, root2.el ]
578 self.assertEqual(["test", "test"],
579 [ c.text for c in root.c ])
580 self.assertEqual(["test", "test"],
581 [ el.text for el in root2.el ])
582
583 root.c[:] = [ c1, c2, c2, c1 ]
584 self.assertEqual(["c1", "c2", "c2", "c1"],
585 [ c.text for c in root.c ])
586
588 Element = self.Element
589 root = Element("root")
590 l = ["c1", "c2", "c3", "c4"]
591 root.c = l
592
593 self.assertEqual(["c1", "c2", "c3", "c4"],
594 [ c.text for c in root.c ])
595 self.assertEqual(l,
596 [ c.text for c in root.c ])
597
598 new_slice = ["cA", "cB"]
599 l[1:2] = new_slice
600 root.c[1:2] = new_slice
601
602 self.assertEqual(["c1", "cA", "cB", "c3", "c4"], l)
603 self.assertEqual(["c1", "cA", "cB", "c3", "c4"],
604 [ c.text for c in root.c ])
605 self.assertEqual(l,
606 [ c.text for c in root.c ])
607
609 Element = self.Element
610 root = Element("root")
611 l = ["c1", "c2", "c3", "c4"]
612 root.c = l
613
614 self.assertEqual(["c1", "c2", "c3", "c4"],
615 [ c.text for c in root.c ])
616 self.assertEqual(l,
617 [ c.text for c in root.c ])
618
619 new_slice = ["cA", "cB"]
620 l[1:1] = new_slice
621 root.c[1:1] = new_slice
622
623 self.assertEqual(["c1", "cA", "cB", "c2", "c3", "c4"], l)
624 self.assertEqual(["c1", "cA", "cB", "c2", "c3", "c4"],
625 [ c.text for c in root.c ])
626 self.assertEqual(l,
627 [ c.text for c in root.c ])
628
630 Element = self.Element
631 root = Element("root")
632 l = ["c1", "c2", "c3", "c4"]
633 root.c = l
634
635 self.assertEqual(["c1", "c2", "c3", "c4"],
636 [ c.text for c in root.c ])
637 self.assertEqual(l,
638 [ c.text for c in root.c ])
639
640 new_slice = ["cA", "cB"]
641 l[-2:-2] = new_slice
642 root.c[-2:-2] = new_slice
643
644 self.assertEqual(["c1", "c2", "cA", "cB", "c3", "c4"], l)
645 self.assertEqual(["c1", "c2", "cA", "cB", "c3", "c4"],
646 [ c.text for c in root.c ])
647 self.assertEqual(l,
648 [ c.text for c in root.c ])
649
657
659 Element = self.Element
660 root = Element("root")
661 l = ["c1", "c2", "c3", "c4"]
662 root.c = l
663
664 self.assertEqual(["c1", "c2", "c3", "c4"],
665 [ c.text for c in root.c ])
666 self.assertEqual(l,
667 [ c.text for c in root.c ])
668
669 new_slice = ["cA", "cB", "cC"]
670 self.assertRaises(
671 ValueError, operator.setitem,
672 l, slice(1,2,-1), new_slice)
673 self.assertRaises(
674 ValueError, operator.setitem,
675 root.c, slice(1,2,-1), new_slice)
676
678 Element = self.Element
679 root = Element("root")
680 l = ["c1", "c2", "c3", "c4"]
681 root.c = l
682
683 self.assertEqual(["c1", "c2", "c3", "c4"],
684 [ c.text for c in root.c ])
685 self.assertEqual(l,
686 [ c.text for c in root.c ])
687
688 new_slice = ["cA", "cB"]
689 l[-1:1:-1] = new_slice
690 root.c[-1:1:-1] = new_slice
691
692 self.assertEqual(["c1", "c2", "cB", "cA"], l)
693 self.assertEqual(["c1", "c2", "cB", "cA"],
694 [ c.text for c in root.c ])
695 self.assertEqual(l,
696 [ c.text for c in root.c ])
697
699 Element = self.Element
700 root = Element("root")
701 l = ["c1", "c2", "c3", "c4"]
702 root.c = l
703
704 self.assertEqual(["c1", "c2", "c3", "c4"],
705 [ c.text for c in root.c ])
706 self.assertEqual(l,
707 [ c.text for c in root.c ])
708
709 new_slice = ["cA", "cB"]
710 l[-1:-4:-2] = new_slice
711 root.c[-1:-4:-2] = new_slice
712
713 self.assertEqual(["c1", "cB", "c3", "cA"], l)
714 self.assertEqual(["c1", "cB", "c3", "cA"],
715 [ c.text for c in root.c ])
716 self.assertEqual(l,
717 [ c.text for c in root.c ])
718
719
720
722 Element = self.Element
723 root = Element("root")
724 root['child'] = ['CHILD1', 'CHILD2']
725 self.assertEqual(["CHILD1", "CHILD2"],
726 [ c.text for c in root.child ])
727
728 self.assertRaises(IndexError, operator.setitem, root.child, -3, 'oob')
729 self.assertRaises(IndexError, operator.setitem, root.child, -300, 'oob')
730 self.assertRaises(IndexError, operator.setitem, root.child, 2, 'oob')
731 self.assertRaises(IndexError, operator.setitem, root.child, 200, 'oob')
732
733 root.child[0] = "child0"
734 root.child[-1] = "child-1"
735 self.assertEqual(["child0", "child-1"],
736 [ c.text for c in root.child ])
737
738 root.child[1] = "child1"
739 root.child[-2] = "child-2"
740 self.assertEqual(["child-2", "child1"],
741 [ c.text for c in root.child ])
742
744
745 Element = self.Element
746 root = Element("root")
747 root['child'] = ['CHILD1', 'CHILD2', 'CHILD3', 'CHILD4']
748 self.assertEqual(["CHILD1", "CHILD2", "CHILD3", "CHILD4"],
749 [ c.text for c in root.child ])
750
751 del root.child[-1]
752 self.assertEqual(["CHILD1", "CHILD2", "CHILD3"],
753 [ c.text for c in root.child ])
754 del root.child[-2]
755 self.assertEqual(["CHILD1", "CHILD3"],
756 [ c.text for c in root.child ])
757 del root.child[0]
758 self.assertEqual(["CHILD3"],
759 [ c.text for c in root.child ])
760 del root.child[-1]
761 self.assertRaises(AttributeError, getattr, root, 'child')
762
770
778
780
781 Element = self.Element
782 root = Element("root")
783
784 root["text"] = "TEST"
785 self.assertEqual(["TEST"],
786 [ c.text for c in root["text"] ])
787
788 root["tail"] = "TEST"
789 self.assertEqual(["TEST"],
790 [ c.text for c in root["tail"] ])
791
792 root["pyval"] = "TEST"
793 self.assertEqual(["TEST"],
794 [ c.text for c in root["pyval"] ])
795
796 root["tag"] = "TEST"
797 self.assertEqual(["TEST"],
798 [ c.text for c in root["tag"] ])
799
807
809 XML = self.XML
810 root = XML('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')
811 self.assertEqual(2, len(root.findall(".//{X}b")))
812 self.assertEqual(3, len(root.findall(".//b")))
813 self.assertEqual(2, len(root.findall("b")))
814
822
837
843
845 Element = self.Element
846 SubElement = self.etree.SubElement
847 root = Element("{objectified}root")
848 root.bool = True
849 self.assertEqual(root.bool, True)
850 self.assertEqual(root.bool + root.bool, True + True)
851 self.assertEqual(True + root.bool, True + root.bool)
852 self.assertEqual(root.bool * root.bool, True * True)
853 self.assertEqual(int(root.bool), int(True))
854 self.assertEqual(hash(root.bool), hash(True))
855 self.assertEqual(complex(root.bool), complex(True))
856 self.assertTrue(isinstance(root.bool, objectify.BoolElement))
857
858 root.bool = False
859 self.assertEqual(root.bool, False)
860 self.assertEqual(root.bool + root.bool, False + False)
861 self.assertEqual(False + root.bool, False + root.bool)
862 self.assertEqual(root.bool * root.bool, False * False)
863 self.assertEqual(int(root.bool), int(False))
864 self.assertEqual(hash(root.bool), hash(False))
865 self.assertEqual(complex(root.bool), complex(False))
866 self.assertTrue(isinstance(root.bool, objectify.BoolElement))
867
876
883
890
897
909
919
940
945
950
955
960
969
974
979
984
991
998
1005
1017
1027
1032
1037
1042
1049
1054
1058
1065
1070
1074
1088
1093
1105
1112
1118
1127
1136
1142
1151
1153 pyval = 1
1154 pytype = "NoneType"
1155 objclass = objectify.NoneElement
1156 value = objectify.DataElement(pyval, _pytype=pytype)
1157 self.assertTrue(isinstance(value, objclass),
1158 "DataElement(%s, _pytype='%s') returns %s, expected %s"
1159 % (pyval, pytype, type(value), objclass))
1160 self.assertEqual(value.text, None)
1161 self.assertEqual(value.pyval, None)
1162
1164
1165 pyval = 1
1166 pytype = "none"
1167 objclass = objectify.NoneElement
1168 value = objectify.DataElement(pyval, _pytype=pytype)
1169 self.assertTrue(isinstance(value, objclass),
1170 "DataElement(%s, _pytype='%s') returns %s, expected %s"
1171 % (pyval, pytype, type(value), objclass))
1172 self.assertEqual(value.text, None)
1173 self.assertEqual(value.pyval, None)
1174
1180 root = Element("{objectified}root")
1181 root.myfloat = MyFloat(5.5)
1182 self.assertTrue(isinstance(root.myfloat, objectify.FloatElement))
1183 self.assertEqual(root.myfloat.get(objectify.PYTYPE_ATTRIBUTE), None)
1184
1186 class MyFloat(float):
1187 pass
1188 value = objectify.DataElement(MyFloat(5.5))
1189 self.assertTrue(isinstance(value, objectify.FloatElement))
1190 self.assertEqual(value, 5.5)
1191 self.assertEqual(value.get(objectify.PYTYPE_ATTRIBUTE), None)
1192
1194 XML = self.XML
1195 root = XML('''\
1196 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1197 <b xsi:type="boolean">true</b>
1198 <b xsi:type="boolean">false</b>
1199 <b xsi:type="boolean">1</b>
1200 <b xsi:type="boolean">0</b>
1201
1202 <f xsi:type="float">5</f>
1203 <f xsi:type="double">5</f>
1204
1205 <s xsi:type="string">5</s>
1206 <s xsi:type="normalizedString">5</s>
1207 <s xsi:type="token">5</s>
1208 <s xsi:type="language">5</s>
1209 <s xsi:type="Name">5</s>
1210 <s xsi:type="NCName">5</s>
1211 <s xsi:type="ID">5</s>
1212 <s xsi:type="IDREF">5</s>
1213 <s xsi:type="ENTITY">5</s>
1214 <s xsi:type="NMTOKEN">5</s>
1215
1216 <l xsi:type="integer">5</l>
1217 <l xsi:type="nonPositiveInteger">5</l>
1218 <l xsi:type="negativeInteger">5</l>
1219 <l xsi:type="long">5</l>
1220 <l xsi:type="nonNegativeInteger">5</l>
1221 <l xsi:type="unsignedLong">5</l>
1222 <l xsi:type="unsignedInt">5</l>
1223 <l xsi:type="positiveInteger">5</l>
1224
1225 <i xsi:type="int">5</i>
1226 <i xsi:type="short">5</i>
1227 <i xsi:type="byte">5</i>
1228 <i xsi:type="unsignedShort">5</i>
1229 <i xsi:type="unsignedByte">5</i>
1230
1231 <n xsi:nil="true"/>
1232 </root>
1233 ''')
1234
1235 for b in root.b:
1236 self.assertTrue(isinstance(b, objectify.BoolElement))
1237 self.assertEqual(True, root.b[0])
1238 self.assertEqual(False, root.b[1])
1239 self.assertEqual(True, root.b[2])
1240 self.assertEqual(False, root.b[3])
1241
1242 for f in root.f:
1243 self.assertTrue(isinstance(f, objectify.FloatElement))
1244 self.assertEqual(5, f)
1245
1246 for s in root.s:
1247 self.assertTrue(isinstance(s, objectify.StringElement))
1248 self.assertEqual("5", s)
1249
1250 for i in root.i:
1251 self.assertTrue(isinstance(i, objectify.IntElement))
1252 self.assertEqual(5, i)
1253
1254 for l in root.l:
1255 self.assertTrue(isinstance(l, objectify.IntElement))
1256 self.assertEqual(5, i)
1257
1258 self.assertTrue(isinstance(root.n, objectify.NoneElement))
1259 self.assertEqual(None, root.n)
1260
1262 XML = self.XML
1263 root = XML('''\
1264 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1265 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1266 <b xsi:type="xsd:boolean">true</b>
1267 <b xsi:type="xsd:boolean">false</b>
1268 <b xsi:type="xsd:boolean">1</b>
1269 <b xsi:type="xsd:boolean">0</b>
1270
1271 <f xsi:type="xsd:float">5</f>
1272 <f xsi:type="xsd:double">5</f>
1273
1274 <s xsi:type="xsd:string">5</s>
1275 <s xsi:type="xsd:normalizedString">5</s>
1276 <s xsi:type="xsd:token">5</s>
1277 <s xsi:type="xsd:language">5</s>
1278 <s xsi:type="xsd:Name">5</s>
1279 <s xsi:type="xsd:NCName">5</s>
1280 <s xsi:type="xsd:ID">5</s>
1281 <s xsi:type="xsd:IDREF">5</s>
1282 <s xsi:type="xsd:ENTITY">5</s>
1283 <s xsi:type="xsd:NMTOKEN">5</s>
1284
1285 <l xsi:type="xsd:integer">5</l>
1286 <l xsi:type="xsd:nonPositiveInteger">5</l>
1287 <l xsi:type="xsd:negativeInteger">5</l>
1288 <l xsi:type="xsd:long">5</l>
1289 <l xsi:type="xsd:nonNegativeInteger">5</l>
1290 <l xsi:type="xsd:unsignedLong">5</l>
1291 <l xsi:type="xsd:unsignedInt">5</l>
1292 <l xsi:type="xsd:positiveInteger">5</l>
1293
1294 <i xsi:type="xsd:int">5</i>
1295 <i xsi:type="xsd:short">5</i>
1296 <i xsi:type="xsd:byte">5</i>
1297 <i xsi:type="xsd:unsignedShort">5</i>
1298 <i xsi:type="xsd:unsignedByte">5</i>
1299
1300 <n xsi:nil="true"/>
1301 </root>
1302 ''')
1303
1304 for b in root.b:
1305 self.assertTrue(isinstance(b, objectify.BoolElement))
1306 self.assertEqual(True, root.b[0])
1307 self.assertEqual(False, root.b[1])
1308 self.assertEqual(True, root.b[2])
1309 self.assertEqual(False, root.b[3])
1310
1311 for f in root.f:
1312 self.assertTrue(isinstance(f, objectify.FloatElement))
1313 self.assertEqual(5, f)
1314
1315 for s in root.s:
1316 self.assertTrue(isinstance(s, objectify.StringElement))
1317 self.assertEqual("5", s)
1318
1319 for i in root.i:
1320 self.assertTrue(isinstance(i, objectify.IntElement))
1321 self.assertEqual(5, i)
1322
1323 for l in root.l:
1324 self.assertTrue(isinstance(l, objectify.IntElement))
1325 self.assertEqual(5, l)
1326
1327 self.assertTrue(isinstance(root.n, objectify.NoneElement))
1328 self.assertEqual(None, root.n)
1329
1331 XML = self.XML
1332 root = XML(_bytes('<root><b>why</b><b>try</b></root>'))
1333 strs = [ str(s) for s in root.b ]
1334 self.assertEqual(["why", "try"],
1335 strs)
1336
1338 XML = self.XML
1339 root = XML(_bytes('<root><b>test</b><b>taste</b><b></b><b/></root>'))
1340 self.assertFalse(root.b[0] < root.b[1])
1341 self.assertFalse(root.b[0] <= root.b[1])
1342 self.assertFalse(root.b[0] == root.b[1])
1343
1344 self.assertTrue(root.b[0] != root.b[1])
1345 self.assertTrue(root.b[0] >= root.b[1])
1346 self.assertTrue(root.b[0] > root.b[1])
1347
1348 self.assertEqual(root.b[0], "test")
1349 self.assertEqual("test", root.b[0])
1350
1351 self.assertEqual("", root.b[2])
1352 self.assertEqual(root.b[2], "")
1353 self.assertEqual("", root.b[3])
1354 self.assertEqual(root.b[3], "")
1355 self.assertEqual(root.b[2], root.b[3])
1356
1357 root.b = "test"
1358 self.assertTrue(root.b)
1359 root.b = ""
1360 self.assertFalse(root.b)
1361 self.assertEqual(root.b, "")
1362 self.assertEqual("", root.b)
1363
1365 XML = self.XML
1366 root = XML(_bytes('<root><b>5</b><b>6</b></root>'))
1367 self.assertTrue(root.b[0] < root.b[1])
1368 self.assertTrue(root.b[0] <= root.b[1])
1369 self.assertTrue(root.b[0] != root.b[1])
1370
1371 self.assertFalse(root.b[0] == root.b[1])
1372 self.assertFalse(root.b[0] >= root.b[1])
1373 self.assertFalse(root.b[0] > root.b[1])
1374
1375 self.assertEqual(root.b[0], 5)
1376 self.assertEqual(5, root.b[0])
1377 self.assertNotEqual(root.b[0], "5")
1378
1379 root.b = 5
1380 self.assertTrue(root.b)
1381 root.b = 0
1382 self.assertFalse(root.b)
1383
1384
1385
1387 XML = self.XML
1388 root = XML(_bytes('<root><b>false</b><b>true</b></root>'))
1389 self.assertTrue(root.b[0] < root.b[1])
1390 self.assertTrue(root.b[0] <= root.b[1])
1391 self.assertTrue(root.b[0] != root.b[1])
1392
1393 self.assertFalse(root.b[0] == root.b[1])
1394 self.assertFalse(root.b[0] >= root.b[1])
1395 self.assertFalse(root.b[0] > root.b[1])
1396
1397 self.assertFalse(root.b[0])
1398 self.assertTrue(root.b[1])
1399
1400 self.assertEqual(root.b[0], False)
1401 self.assertEqual(False, root.b[0])
1402 self.assertTrue(root.b[0] < 5)
1403 self.assertTrue(5 > root.b[0])
1404
1405 root.b = True
1406 self.assertTrue(root.b)
1407 root.b = False
1408 self.assertFalse(root.b)
1409
1411 XML = self.XML
1412 root = XML(_bytes("""
1413 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1414 <b xsi:nil="true"></b><b xsi:nil="true"/>
1415 </root>"""))
1416 self.assertTrue(root.b[0] == root.b[1])
1417 self.assertFalse(root.b[0])
1418 self.assertEqual(root.b[0], None)
1419 self.assertEqual(None, root.b[0])
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1435
1442
1446
1448 XML = self.XML
1449 root = XML(_bytes('''\
1450 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1451 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1452 <b>5</b>
1453 <b>test</b>
1454 <c>1.1</c>
1455 <c>\uF8D2</c>
1456 <x>true</x>
1457 <n xsi:nil="true" />
1458 <n></n>
1459 <b xsi:type="double">5</b>
1460 <b xsi:type="float">5</b>
1461 <s xsi:type="string">23</s>
1462 <s py:pytype="str">42</s>
1463 <f py:pytype="float">300</f>
1464 <l py:pytype="long">2</l>
1465 <t py:pytype="TREE"></t>
1466 </a>
1467 '''))
1468 objectify.annotate(root)
1469
1470 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1471 for c in root.iterchildren() ]
1472 self.assertEqual("int", child_types[ 0])
1473 self.assertEqual("str", child_types[ 1])
1474 self.assertEqual("float", child_types[ 2])
1475 self.assertEqual("str", child_types[ 3])
1476 self.assertEqual("bool", child_types[ 4])
1477 self.assertEqual("NoneType", child_types[ 5])
1478 self.assertEqual(None, child_types[ 6])
1479 self.assertEqual("float", child_types[ 7])
1480 self.assertEqual("float", child_types[ 8])
1481 self.assertEqual("str", child_types[ 9])
1482 self.assertEqual("int", child_types[10])
1483 self.assertEqual("int", child_types[11])
1484 self.assertEqual("int", child_types[12])
1485 self.assertEqual(None, child_types[13])
1486
1487 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1488
1508
1510 XML = self.XML
1511 root = XML(_bytes('''\
1512 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1513 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1514 <b>5</b>
1515 <b>test</b>
1516 <c>1.1</c>
1517 <c>\uF8D2</c>
1518 <x>true</x>
1519 <n xsi:nil="true" />
1520 <n></n>
1521 <b xsi:type="double">5</b>
1522 <b xsi:type="float">5</b>
1523 <s xsi:type="string">23</s>
1524 <s py:pytype="str">42</s>
1525 <f py:pytype="float">300</f>
1526 <l py:pytype="long">2</l>
1527 <t py:pytype="TREE"></t>
1528 </a>
1529 '''))
1530 objectify.annotate(root, ignore_old=False)
1531
1532 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1533 for c in root.iterchildren() ]
1534 self.assertEqual("int", child_types[ 0])
1535 self.assertEqual("str", child_types[ 1])
1536 self.assertEqual("float", child_types[ 2])
1537 self.assertEqual("str", child_types[ 3])
1538 self.assertEqual("bool", child_types[ 4])
1539 self.assertEqual("NoneType", child_types[ 5])
1540 self.assertEqual(None, child_types[ 6])
1541 self.assertEqual("float", child_types[ 7])
1542 self.assertEqual("float", child_types[ 8])
1543 self.assertEqual("str", child_types[ 9])
1544 self.assertEqual("str", child_types[10])
1545 self.assertEqual("float", child_types[11])
1546 self.assertEqual("int", child_types[12])
1547 self.assertEqual(TREE_PYTYPE, child_types[13])
1548
1549 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1550
1552 XML = self.XML
1553 root = XML(_bytes('''\
1554 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1555 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1556 <b>5</b>
1557 <b>test</b>
1558 <c>1.1</c>
1559 <c>\uF8D2</c>
1560 <x>true</x>
1561 <n xsi:nil="true" />
1562 <n></n>
1563 <b xsi:type="double">5</b>
1564 <b xsi:type="float">5</b>
1565 <s xsi:type="string">23</s>
1566 <s py:pytype="str">42</s>
1567 <f py:pytype="float">300</f>
1568 <l py:pytype="long">2</l>
1569 <t py:pytype="TREE"></t>
1570 </a>
1571 '''))
1572 objectify.annotate(root, ignore_old=False, ignore_xsi=False,
1573 annotate_xsi=1, annotate_pytype=1)
1574
1575
1576 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1577 for c in root.iterchildren() ]
1578 self.assertEqual("int", child_types[ 0])
1579 self.assertEqual("str", child_types[ 1])
1580 self.assertEqual("float", child_types[ 2])
1581 self.assertEqual("str", child_types[ 3])
1582 self.assertEqual("bool", child_types[ 4])
1583 self.assertEqual("NoneType", child_types[ 5])
1584 self.assertEqual(None, child_types[ 6])
1585 self.assertEqual("float", child_types[ 7])
1586 self.assertEqual("float", child_types[ 8])
1587 self.assertEqual("str", child_types[ 9])
1588 self.assertEqual("str", child_types[10])
1589 self.assertEqual("float", child_types[11])
1590 self.assertEqual("int", child_types[12])
1591 self.assertEqual(TREE_PYTYPE, child_types[13])
1592
1593 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1594
1595 child_xsitypes = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1596 for c in root.iterchildren() ]
1597
1598
1599 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1600 for c in root.iterchildren() ]
1601 self.assertEqual("xsd:integer", child_types[ 0])
1602 self.assertEqual("xsd:string", child_types[ 1])
1603 self.assertEqual("xsd:double", child_types[ 2])
1604 self.assertEqual("xsd:string", child_types[ 3])
1605 self.assertEqual("xsd:boolean", child_types[ 4])
1606 self.assertEqual(None, child_types[ 5])
1607 self.assertEqual(None, child_types[ 6])
1608 self.assertEqual("xsd:double", child_types[ 7])
1609 self.assertEqual("xsd:float", child_types[ 8])
1610 self.assertEqual("xsd:string", child_types[ 9])
1611 self.assertEqual("xsd:string", child_types[10])
1612 self.assertEqual("xsd:double", child_types[11])
1613 self.assertEqual("xsd:integer", child_types[12])
1614 self.assertEqual(None, child_types[13])
1615
1616 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1617
1619 XML = self.XML
1620 root = XML(_bytes('''\
1621 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1622 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1623 <b>5</b>
1624 <b>test</b>
1625 <c>1.1</c>
1626 <c>\uF8D2</c>
1627 <x>true</x>
1628 <n xsi:nil="true" />
1629 <n></n>
1630 <b xsi:type="double">5</b>
1631 <b xsi:type="float">5</b>
1632 <s xsi:type="string">23</s>
1633 <s py:pytype="str">42</s>
1634 <f py:pytype="float">300</f>
1635 <l py:pytype="long">2</l>
1636 <t py:pytype="TREE"></t>
1637 </a>
1638 '''))
1639 objectify.xsiannotate(root, ignore_old=False)
1640
1641 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1642 for c in root.iterchildren() ]
1643 self.assertEqual("xsd:integer", child_types[ 0])
1644 self.assertEqual("xsd:string", child_types[ 1])
1645 self.assertEqual("xsd:double", child_types[ 2])
1646 self.assertEqual("xsd:string", child_types[ 3])
1647 self.assertEqual("xsd:boolean", child_types[ 4])
1648 self.assertEqual(None, child_types[ 5])
1649 self.assertEqual(None, child_types[ 6])
1650 self.assertEqual("xsd:double", child_types[ 7])
1651 self.assertEqual("xsd:float", child_types[ 8])
1652 self.assertEqual("xsd:string", child_types[ 9])
1653 self.assertEqual("xsd:string", child_types[10])
1654 self.assertEqual("xsd:double", child_types[11])
1655 self.assertEqual("xsd:integer", child_types[12])
1656 self.assertEqual(None, child_types[13])
1657
1659 XML = self.XML
1660 root = XML(_bytes('''\
1661 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1662 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1663 <b>5</b>
1664 <b>test</b>
1665 <c>1.1</c>
1666 <c>\uF8D2</c>
1667 <x>true</x>
1668 <n xsi:nil="true" />
1669 <n></n>
1670 <b xsi:type="double">5</b>
1671 <b xsi:type="float">5</b>
1672 <s xsi:type="string">23</s>
1673 <s py:pytype="str">42</s>
1674 <f py:pytype="float">300</f>
1675 <l py:pytype="long">2</l>
1676 <t py:pytype="TREE"></t>
1677 </a>
1678 '''))
1679 objectify.pyannotate(root, ignore_old=True)
1680
1681 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1682 for c in root.iterchildren() ]
1683 self.assertEqual("int", child_types[ 0])
1684 self.assertEqual("str", child_types[ 1])
1685 self.assertEqual("float", child_types[ 2])
1686 self.assertEqual("str", child_types[ 3])
1687 self.assertEqual("bool", child_types[ 4])
1688 self.assertEqual("NoneType", child_types[ 5])
1689 self.assertEqual(None, child_types[ 6])
1690 self.assertEqual("float", child_types[ 7])
1691 self.assertEqual("float", child_types[ 8])
1692 self.assertEqual("str", child_types[ 9])
1693 self.assertEqual("int", child_types[10])
1694 self.assertEqual("int", child_types[11])
1695 self.assertEqual("int", child_types[12])
1696 self.assertEqual(None, child_types[13])
1697
1698 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1699
1719
1721 XML = self.XML
1722 root = XML('''\
1723 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1724 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1725 <b>5</b>
1726 <b>test</b>
1727 <c>1.1</c>
1728 <c>\uF8D2</c>
1729 <x>true</x>
1730 <n xsi:nil="true" />
1731 <n></n>
1732 <b xsi:type="double">5</b>
1733 <b xsi:type="float">5</b>
1734 <s xsi:type="string">23</s>
1735 <s py:pytype="str">42</s>
1736 <f py:pytype="float">300</f>
1737 <l py:pytype="long">2</l>
1738 <t py:pytype="TREE"></t>
1739 </a>
1740 ''')
1741 objectify.pyannotate(root)
1742
1743 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1744 for c in root.iterchildren() ]
1745 self.assertEqual("int", child_types[ 0])
1746 self.assertEqual("str", child_types[ 1])
1747 self.assertEqual("float", child_types[ 2])
1748 self.assertEqual("str", child_types[ 3])
1749 self.assertEqual("bool", child_types[ 4])
1750 self.assertEqual("NoneType", child_types[ 5])
1751 self.assertEqual(None, child_types[ 6])
1752 self.assertEqual("float", child_types[ 7])
1753 self.assertEqual("float", child_types[ 8])
1754 self.assertEqual("str", child_types[ 9])
1755 self.assertEqual("str", child_types[10])
1756 self.assertEqual("float", child_types[11])
1757 self.assertEqual("int", child_types[12])
1758 self.assertEqual(TREE_PYTYPE, child_types[13])
1759
1760 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1761
1763 XML = self.XML
1764 root = XML(_bytes('''\
1765 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1766 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1767 <b>5</b>
1768 <b>test</b>
1769 <c>1.1</c>
1770 <c>\uF8D2</c>
1771 <x>true</x>
1772 <n xsi:nil="true" />
1773 <n></n>
1774 <b xsi:type="double">5</b>
1775 <b xsi:type="float">5</b>
1776 <s xsi:type="string">23</s>
1777 <s py:pytype="str">42</s>
1778 <f py:pytype="float">300</f>
1779 <l py:pytype="long">2</l>
1780 <t py:pytype="TREE"></t>
1781 </a>
1782 '''))
1783 objectify.xsiannotate(root, ignore_old=True)
1784
1785 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1786 for c in root.iterchildren() ]
1787 self.assertEqual("xsd:integer", child_types[ 0])
1788 self.assertEqual("xsd:string", child_types[ 1])
1789 self.assertEqual("xsd:double", child_types[ 2])
1790 self.assertEqual("xsd:string", child_types[ 3])
1791 self.assertEqual("xsd:boolean", child_types[ 4])
1792 self.assertEqual(None, child_types[ 5])
1793 self.assertEqual(None, child_types[ 6])
1794 self.assertEqual("xsd:integer", child_types[ 7])
1795 self.assertEqual("xsd:integer", child_types[ 8])
1796 self.assertEqual("xsd:integer", child_types[ 9])
1797 self.assertEqual("xsd:string", child_types[10])
1798 self.assertEqual("xsd:double", child_types[11])
1799 self.assertEqual("xsd:integer", child_types[12])
1800 self.assertEqual(None, child_types[13])
1801
1802 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1803
1805 XML = self.XML
1806 root = XML(_bytes('''\
1807 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1808 xmlns:py="http://codespeak.net/lxml/objectify/pytype">
1809 <b>5</b>
1810 <b>test</b>
1811 <c>1.1</c>
1812 <c>\uF8D2</c>
1813 <x>true</x>
1814 <n xsi:nil="true" />
1815 <n></n>
1816 <b xsi:type="double">5</b>
1817 <b xsi:type="float">5</b>
1818 <s xsi:type="string">23</s>
1819 <s py:pytype="str">42</s>
1820 <f py:pytype="float">300</f>
1821 <l py:pytype="long">2</l>
1822 <t py:pytype="TREE"></t>
1823 </a>
1824 '''))
1825 objectify.deannotate(root)
1826
1827 for c in root.getiterator():
1828 self.assertEqual(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1829 self.assertEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1830
1831 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_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 <b>5</b>
1839 <b>test</b>
1840 <c>1.1</c>
1841 <c>\uF8D2</c>
1842 <x>true</x>
1843 <n xsi:nil="true" />
1844 <n></n>
1845 <b xsi:type="double">5</b>
1846 <b xsi:type="float">5</b>
1847 <s xsi:type="string">23</s>
1848 <s py:pytype="str">42</s>
1849 <f py:pytype="float">300</f>
1850 <l py:pytype="long">2</l>
1851 <t py:pytype="TREE"></t>
1852 </a>
1853 '''))
1854 objectify.annotate(
1855 root, ignore_old=False, ignore_xsi=False, annotate_xsi=True,
1856 empty_pytype='str', empty_type='string')
1857 objectify.deannotate(root, pytype=False, xsi=False, xsi_nil=True)
1858
1859 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1860 for c in root.iterchildren() ]
1861 self.assertEqual("xsd:integer", child_types[ 0])
1862 self.assertEqual("xsd:string", child_types[ 1])
1863 self.assertEqual("xsd:double", child_types[ 2])
1864 self.assertEqual("xsd:string", child_types[ 3])
1865 self.assertEqual("xsd:boolean", child_types[ 4])
1866 self.assertEqual(None, child_types[ 5])
1867 self.assertEqual("xsd:string", child_types[ 6])
1868 self.assertEqual("xsd:double", child_types[ 7])
1869 self.assertEqual("xsd:float", child_types[ 8])
1870 self.assertEqual("xsd:string", child_types[ 9])
1871 self.assertEqual("xsd:string", child_types[10])
1872 self.assertEqual("xsd:double", child_types[11])
1873 self.assertEqual("xsd:integer", child_types[12])
1874 self.assertEqual(None, child_types[13])
1875
1876 self.assertEqual(None, root.n.get(XML_SCHEMA_NIL_ATTR))
1877
1878 for c in root.iterchildren():
1879 self.assertNotEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1880
1881 if (c.get(objectify.PYTYPE_ATTRIBUTE) not in [TREE_PYTYPE,
1882 "NoneType"]):
1883 self.assertNotEqual(
1884 None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1885
1887 XML = self.XML
1888 root = XML(_bytes('''\
1889 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1890 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1891 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1892 <b>5</b>
1893 <b>test</b>
1894 <c>1.1</c>
1895 <c>\uF8D2</c>
1896 <x>true</x>
1897 <n xsi:nil="true" />
1898 <n></n>
1899 <b xsi:type="xsd:double">5</b>
1900 <b xsi:type="xsd:float">5</b>
1901 <s xsi:type="xsd:string">23</s>
1902 <s py:pytype="str">42</s>
1903 <f py:pytype="float">300</f>
1904 <l py:pytype="long">2</l>
1905 <t py:pytype="TREE"></t>
1906 </a>
1907 '''))
1908 objectify.annotate(root)
1909 objectify.deannotate(root, pytype=False)
1910
1911 child_types = [ c.get(objectify.PYTYPE_ATTRIBUTE)
1912 for c in root.iterchildren() ]
1913 self.assertEqual("int", child_types[ 0])
1914 self.assertEqual("str", child_types[ 1])
1915 self.assertEqual("float", child_types[ 2])
1916 self.assertEqual("str", child_types[ 3])
1917 self.assertEqual("bool", child_types[ 4])
1918 self.assertEqual("NoneType", child_types[ 5])
1919 self.assertEqual(None, child_types[ 6])
1920 self.assertEqual("float", child_types[ 7])
1921 self.assertEqual("float", child_types[ 8])
1922 self.assertEqual("str", child_types[ 9])
1923 self.assertEqual("int", child_types[10])
1924 self.assertEqual("int", child_types[11])
1925 self.assertEqual("int", child_types[12])
1926 self.assertEqual(None, child_types[13])
1927
1928 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1929
1930 for c in root.getiterator():
1931 self.assertEqual(None, c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR))
1932
1934 XML = self.XML
1935 root = XML(_bytes('''\
1936 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1937 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
1938 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
1939 <b xsi:type="xsd:int">5</b>
1940 <b xsi:type="xsd:string">test</b>
1941 <c xsi:type="xsd:float">1.1</c>
1942 <c xsi:type="xsd:string">\uF8D2</c>
1943 <x xsi:type="xsd:boolean">true</x>
1944 <n xsi:nil="true" />
1945 <n></n>
1946 <b xsi:type="xsd:double">5</b>
1947 <b xsi:type="xsd:float">5</b>
1948 <s xsi:type="xsd:string">23</s>
1949 <s xsi:type="xsd:string">42</s>
1950 <f xsi:type="xsd:float">300</f>
1951 <l xsi:type="xsd:long">2</l>
1952 <t py:pytype="TREE"></t>
1953 </a>
1954 '''))
1955 objectify.annotate(root)
1956 objectify.deannotate(root, xsi=False)
1957
1958 child_types = [ c.get(XML_SCHEMA_INSTANCE_TYPE_ATTR)
1959 for c in root.iterchildren() ]
1960 self.assertEqual("xsd:int", child_types[ 0])
1961 self.assertEqual("xsd:string", child_types[ 1])
1962 self.assertEqual("xsd:float", child_types[ 2])
1963 self.assertEqual("xsd:string", child_types[ 3])
1964 self.assertEqual("xsd:boolean", child_types[ 4])
1965 self.assertEqual(None, child_types[ 5])
1966 self.assertEqual(None, child_types[ 6])
1967 self.assertEqual("xsd:double", child_types[ 7])
1968 self.assertEqual("xsd:float", child_types[ 8])
1969 self.assertEqual("xsd:string", child_types[ 9])
1970 self.assertEqual("xsd:string", child_types[10])
1971 self.assertEqual("xsd:float", child_types[11])
1972 self.assertEqual("xsd:long", child_types[12])
1973 self.assertEqual(None, child_types[13])
1974
1975 self.assertEqual("true", root.n.get(XML_SCHEMA_NIL_ATTR))
1976
1977 for c in root.getiterator():
1978 self.assertEqual(None, c.get(objectify.PYTYPE_ATTRIBUTE))
1979
1981 XML = self.XML
1982
1983 xml = _bytes('''\
1984 <a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
1985 <b>5</b>
1986 <b>test</b>
1987 <c>1.1</c>
1988 <c>\uF8D2</c>
1989 <x>true</x>
1990 <n xsi:nil="true" />
1991 <n></n>
1992 <b xsi:type="double">5</b>
1993 </a>
1994 ''')
1995
1996 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
1997 objectify.set_pytype_attribute_tag("{TEST}test")
1998
1999 root = XML(xml)
2000 objectify.annotate(root)
2001
2002 attribs = root.xpath("//@py:%s" % pytype_name,
2003 namespaces={"py" : pytype_ns})
2004 self.assertEqual(0, len(attribs))
2005 attribs = root.xpath("//@py:test",
2006 namespaces={"py" : "TEST"})
2007 self.assertEqual(7, len(attribs))
2008
2009 objectify.set_pytype_attribute_tag()
2010 pytype_ns, pytype_name = objectify.PYTYPE_ATTRIBUTE[1:].split('}')
2011
2012 self.assertNotEqual("test", pytype_ns.lower())
2013 self.assertNotEqual("test", pytype_name.lower())
2014
2015 root = XML(xml)
2016 attribs = root.xpath("//@py:%s" % pytype_name,
2017 namespaces={"py" : pytype_ns})
2018 self.assertEqual(0, len(attribs))
2019
2020 objectify.annotate(root)
2021 attribs = root.xpath("//@py:%s" % pytype_name,
2022 namespaces={"py" : pytype_ns})
2023 self.assertEqual(7, len(attribs))
2024
2032
2033 def checkMyType(s):
2034 return True
2035
2036 pytype = objectify.PyType("mytype", checkMyType, NewType)
2037 self.assertTrue(pytype not in objectify.getRegisteredTypes())
2038 pytype.register()
2039 self.assertTrue(pytype in objectify.getRegisteredTypes())
2040 pytype.unregister()
2041 self.assertTrue(pytype not in objectify.getRegisteredTypes())
2042
2043 pytype.register(before = [objectify.getRegisteredTypes()[0].name])
2044 self.assertEqual(pytype, objectify.getRegisteredTypes()[0])
2045 pytype.unregister()
2046
2047 pytype.register(after = [objectify.getRegisteredTypes()[0].name])
2048 self.assertNotEqual(pytype, objectify.getRegisteredTypes()[0])
2049 pytype.unregister()
2050
2051 self.assertRaises(ValueError, pytype.register,
2052 before = [objectify.getRegisteredTypes()[0].name],
2053 after = [objectify.getRegisteredTypes()[1].name])
2054
2056 from datetime import datetime
2057 def parse_date(value):
2058 if len(value) != 14:
2059 raise ValueError(value)
2060 Y = int(value[0:4])
2061 M = int(value[4:6])
2062 D = int(value[6:8])
2063 h = int(value[8:10])
2064 m = int(value[10:12])
2065 s = int(value[12:14])
2066 return datetime(Y, M, D, h, m, s)
2067
2068 def stringify_date(date):
2069 return date.strftime("%Y%m%d%H%M%S")
2070
2071 class DatetimeElement(objectify.ObjectifiedDataElement):
2072 def pyval(self):
2073 return parse_date(self.text)
2074 pyval = property(pyval)
2075
2076 datetime_type = objectify.PyType(
2077 "datetime", parse_date, DatetimeElement, stringify_date)
2078 datetime_type.xmlSchemaTypes = "dateTime"
2079 datetime_type.register()
2080
2081 NAMESPACE = "http://foo.net/xmlns"
2082 NAMESPACE_MAP = {'ns': NAMESPACE}
2083
2084 r = objectify.Element("{%s}root" % NAMESPACE, nsmap=NAMESPACE_MAP)
2085 time = datetime.now()
2086 r.date = time
2087
2088 self.assertTrue(isinstance(r.date, DatetimeElement))
2089 self.assertTrue(isinstance(r.date.pyval, datetime))
2090
2091 self.assertEqual(r.date.pyval, parse_date(stringify_date(time)))
2092 self.assertEqual(r.date.text, stringify_date(time))
2093
2094 r.date = objectify.E.date(time)
2095
2096 self.assertTrue(isinstance(r.date, DatetimeElement))
2097 self.assertTrue(isinstance(r.date.pyval, datetime))
2098
2099 self.assertEqual(r.date.pyval, parse_date(stringify_date(time)))
2100 self.assertEqual(r.date.text, stringify_date(time))
2101
2102 date = objectify.DataElement(time)
2103
2104 self.assertTrue(isinstance(date, DatetimeElement))
2105 self.assertTrue(isinstance(date.pyval, datetime))
2106
2107 self.assertEqual(date.pyval, parse_date(stringify_date(time)))
2108 self.assertEqual(date.text, stringify_date(time))
2109
2115
2121
2126
2135
2142
2150
2153
2156
2175
2180
2185
2190
2195
2215
2217 root = self.XML(xml_str)
2218 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[0]'] )
2219 self.assertEqual(root.c1.c2.text, path(root).text)
2220
2221 path = objectify.ObjectPath( ['root', 'c1[0]', 'c2[2]'] )
2222 self.assertEqual(root.c1.c2[2].text, path(root).text)
2223
2224 path = objectify.ObjectPath( ['root', 'c1', 'c2[2]'] )
2225 self.assertEqual(root.c1.c2[2].text, path(root).text)
2226
2227 path = objectify.ObjectPath( ['root', 'c1', 'c2[-1]'] )
2228 self.assertEqual(root.c1.c2[-1].text, path(root).text)
2229
2230 path = objectify.ObjectPath( ['root', 'c1', 'c2[-3]'] )
2231 self.assertEqual(root.c1.c2[-3].text, path(root).text)
2232
2234 self.assertRaises(ValueError, objectify.ObjectPath,
2235 "root.c1[0].c2[-1-2]")
2236 self.assertRaises(ValueError, objectify.ObjectPath,
2237 ['root', 'c1[0]', 'c2[-1-2]'])
2238
2239 self.assertRaises(ValueError, objectify.ObjectPath,
2240 "root[2].c1.c2")
2241 self.assertRaises(ValueError, objectify.ObjectPath,
2242 ['root[2]', 'c1', 'c2'])
2243
2244 self.assertRaises(ValueError, objectify.ObjectPath,
2245 [])
2246 self.assertRaises(ValueError, objectify.ObjectPath,
2247 ['', '', ''])
2248
2250 root = self.XML(xml_str)
2251 path = objectify.ObjectPath("root.c1[9999].c2")
2252 self.assertRaises(AttributeError, path, root)
2253
2254 path = objectify.ObjectPath("root.c1[0].c2[9999]")
2255 self.assertRaises(AttributeError, path, root)
2256
2257 path = objectify.ObjectPath(".c1[9999].c2[0]")
2258 self.assertRaises(AttributeError, path, root)
2259
2260 path = objectify.ObjectPath("root.c1[-2].c2")
2261 self.assertRaises(AttributeError, path, root)
2262
2263 path = objectify.ObjectPath("root.c1[0].c2[-4]")
2264 self.assertRaises(AttributeError, path, root)
2265
2279
2281 root = self.XML(xml_str)
2282 path = objectify.ObjectPath( ['{objectified}root', 'c1', 'c2'] )
2283 self.assertEqual(root.c1.c2.text, path.find(root).text)
2284 path = objectify.ObjectPath( ['{objectified}root', '{objectified}c1', 'c2'] )
2285 self.assertEqual(root.c1.c2.text, path.find(root).text)
2286 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2'] )
2287 self.assertEqual(root.c1.c2.text, path.find(root).text)
2288 path = objectify.ObjectPath( ['root', '{objectified}c1', '{objectified}c2[2]'] )
2289 self.assertEqual(root.c1.c2[2].text, path.find(root).text)
2290 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2'] )
2291 self.assertEqual(root.c1.c2.text, path.find(root).text)
2292 path = objectify.ObjectPath( ['root', 'c1', '{objectified}c2[2]'] )
2293 self.assertEqual(root.c1.c2[2].text, path.find(root).text)
2294 path = objectify.ObjectPath( ['root', 'c1', '{otherNS}c2'] )
2295 self.assertEqual(getattr(root.c1, '{otherNS}c2').text,
2296 path.find(root).text)
2297
2310
2325
2337
2351
2353 root = self.XML(xml_str)
2354 path = objectify.ObjectPath( "root.c1.c99" )
2355 self.assertRaises(AttributeError, path.find, root)
2356
2357 new_el = self.Element("{objectified}test")
2358 new_el.a = ["TEST1", "TEST2"]
2359 new_el.a[0].set("myattr", "ATTR1")
2360 new_el.a[1].set("myattr", "ATTR2")
2361
2362 path.setattr(root, list(new_el.a))
2363
2364 self.assertEqual(2, len(root.c1.c99))
2365 self.assertEqual("ATTR1", root.c1.c99[0].get("myattr"))
2366 self.assertEqual("TEST1", root.c1.c99[0].text)
2367 self.assertEqual("ATTR2", root.c1.c99[1].get("myattr"))
2368 self.assertEqual("TEST2", root.c1.c99[1].text)
2369 self.assertEqual("TEST1", path(root).text)
2370
2379
2393
2405
2419
2434
2436 root = self.XML(xml_str)
2437 self.assertEqual(
2438 ['{objectified}root', '{objectified}root.c1',
2439 '{objectified}root.c1.c2',
2440 '{objectified}root.c1.c2[1]', '{objectified}root.c1.c2[2]',
2441 '{objectified}root.c1.{otherNS}c2', '{objectified}root.c1.{}c2'],
2442 root.descendantpaths())
2443
2445 root = self.XML(xml_str)
2446 self.assertEqual(
2447 ['{objectified}c1', '{objectified}c1.c2',
2448 '{objectified}c1.c2[1]', '{objectified}c1.c2[2]',
2449 '{objectified}c1.{otherNS}c2', '{objectified}c1.{}c2'],
2450 root.c1.descendantpaths())
2451
2453 root = self.XML(xml_str)
2454 self.assertEqual(
2455 ['root.{objectified}c1', 'root.{objectified}c1.c2',
2456 'root.{objectified}c1.c2[1]', 'root.{objectified}c1.c2[2]',
2457 'root.{objectified}c1.{otherNS}c2',
2458 'root.{objectified}c1.{}c2'],
2459 root.c1.descendantpaths('root'))
2460
2472
2485
2489
2493
2497
2503
2508
2510 import pickle
2511 if isinstance(stringOrElt, (etree._Element, etree._ElementTree)):
2512 elt = stringOrElt
2513 else:
2514 elt = self.XML(stringOrElt)
2515 out = BytesIO()
2516 pickle.dump(elt, out)
2517
2518 new_elt = pickle.loads(out.getvalue())
2519 self.assertEqual(
2520 etree.tostring(new_elt),
2521 etree.tostring(elt))
2522
2523
2524
2529
2534
2539
2544
2549
2554
2559
2564
2566 E = objectify.E
2567 DataElement = objectify.DataElement
2568 root = E.root("text", E.sub(E.subsub()), "tail", DataElement(1),
2569 DataElement(2.0))
2570 self.assertTrue(isinstance(root, objectify.ObjectifiedElement))
2571 self.assertEqual(root.text, "text")
2572 self.assertTrue(isinstance(root.sub, objectify.ObjectifiedElement))
2573 self.assertEqual(root.sub.tail, "tail")
2574 self.assertTrue(isinstance(root.sub.subsub, objectify.StringElement))
2575 self.assertEqual(len(root.value), 2)
2576 self.assertTrue(isinstance(root.value[0], objectify.IntElement))
2577 self.assertTrue(isinstance(root.value[1], objectify.FloatElement))
2578
2585
2586 attr = Attribute()
2587 self.assertEqual(attr.text, None)
2588 self.assertEqual(attr.get("datatype"), "TYPE")
2589 self.assertEqual(attr.get("range"), "0.,1.")
2590
2595
2602
2607
2613
2615 root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
2616 self.assertEqual(root.base, "http://no/such/url")
2617 self.assertEqual(
2618 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2619 root.base = "https://secret/url"
2620 self.assertEqual(root.base, "https://secret/url")
2621 self.assertEqual(
2622 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2623 "https://secret/url")
2624
2626 root = objectify.XML(_bytes("<root/>"), base_url="http://no/such/url")
2627 self.assertEqual(root.base, "http://no/such/url")
2628 self.assertEqual(
2629 root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
2630 root.set('{http://www.w3.org/XML/1998/namespace}base',
2631 "https://secret/url")
2632 self.assertEqual(root.base, "https://secret/url")
2633 self.assertEqual(
2634 root.get('{http://www.w3.org/XML/1998/namespace}base'),
2635 "https://secret/url")
2636
2638 XML = self.XML
2639
2640 xml = _bytes('''\
2641 <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
2642 <i>5</i>
2643 <i>-5</i>
2644 <l>4294967296</l>
2645 <l>-4294967296</l>
2646 <f>1.1</f>
2647 <b>true</b>
2648 <b>false</b>
2649 <s>Strange things happen, where strings collide</s>
2650 <s>True</s>
2651 <s>False</s>
2652 <s>t</s>
2653 <s>f</s>
2654 <s></s>
2655 <s>None</s>
2656 <n xsi:nil="true" />
2657 </root>
2658 ''')
2659 root = XML(xml)
2660
2661 for i in root.i:
2662 self.assertTrue(isinstance(i, objectify.IntElement))
2663 for l in root.l:
2664 self.assertTrue(isinstance(l, objectify.IntElement))
2665 for f in root.f:
2666 self.assertTrue(isinstance(f, objectify.FloatElement))
2667 for b in root.b:
2668 self.assertTrue(isinstance(b, objectify.BoolElement))
2669 self.assertEqual(True, root.b[0])
2670 self.assertEqual(False, root.b[1])
2671 for s in root.s:
2672 self.assertTrue(isinstance(s, objectify.StringElement))
2673 self.assertTrue(isinstance(root.n, objectify.NoneElement))
2674 self.assertEqual(None, root.n)
2675
2677 suite = unittest.TestSuite()
2678 suite.addTests([unittest.makeSuite(ObjectifyTestCase)])
2679 suite.addTests(doctest.DocTestSuite(objectify))
2680 suite.addTests([make_doctest('../../../doc/objectify.txt')])
2681 return suite
2682
2683 if __name__ == '__main__':
2684 print('to test use test.py %s' % __file__)
2685