Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(30)

Side by Side Diff: Modules/_elementtree.c

Issue 207048: merge upstream ElementTree 1.3 and cElementTree 1.0.6 in /python/trunk/ (Closed) Base URL: http://svn.python.org/view/*checkout*/python/trunk/
Patch Set: Merge *all* tests from upstream. Fix refleaks on ParseError and E.attrib. Created 14 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Lib/xml/etree/__init__.py ('k') | Modules/celementtree.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * ElementTree 2 * ElementTree
3 * $Id: _elementtree.c 2657 2006-03-12 20:50:32Z fredrik $ 3 * $Id: _elementtree.c 3469 2009-01-10 14:30:13Z fredrik $
4 * 4 *
5 * elementtree accelerator 5 * elementtree accelerator
6 * 6 *
7 * History: 7 * History:
8 * 1999-06-20 fl created (as part of sgmlop) 8 * 1999-06-20 fl created (as part of sgmlop)
9 * 2001-05-29 fl effdom edition 9 * 2001-05-29 fl effdom edition
10 * 2001-06-05 fl backported to unix; fixed bogus free in clear
11 * 2001-07-10 fl added findall helper
12 * 2003-02-27 fl elementtree edition (alpha) 10 * 2003-02-27 fl elementtree edition (alpha)
13 * 2004-06-03 fl updates for elementtree 1.2 11 * 2004-06-03 fl updates for elementtree 1.2
14 * 2005-01-05 fl added universal name cache, Element/SubElement factories 12 * 2005-01-05 fl added universal name cache, Element/SubElement factories
15 * 2005-01-06 fl moved python helpers into C module; removed 1.5.2 support 13 * 2005-01-06 fl moved python helpers into C module; removed 1.5.2 support
16 * 2005-01-07 fl added 2.1 support; work around broken __copy__ in 2.3 14 * 2005-01-07 fl added 2.1 support; work around broken __copy__ in 2.3
17 * 2005-01-08 fl added makeelement method; fixed path support 15 * 2005-01-08 fl added makeelement method; fixed path support
18 * 2005-01-10 fl optimized memory usage 16 * 2005-01-10 fl optimized memory usage
19 * 2005-01-11 fl first public release (cElementTree 0.8) 17 * 2005-01-11 fl first public release (cElementTree 0.8)
20 * 2005-01-12 fl split element object into base and extras 18 * 2005-01-12 fl split element object into base and extras
21 * 2005-01-13 fl use tagged pointers for tail/text (cElementTree 0.9) 19 * 2005-01-13 fl use tagged pointers for tail/text (cElementTree 0.9)
22 * 2005-01-17 fl added treebuilder close method 20 * 2005-01-17 fl added treebuilder close method
23 * 2005-01-17 fl fixed crash in getchildren 21 * 2005-01-17 fl fixed crash in getchildren
24 * 2005-01-18 fl removed observer api, added iterparse (cElementTree 0.9.3) 22 * 2005-01-18 fl removed observer api, added iterparse (cElementTree 0.9.3)
25 * 2005-01-23 fl revised iterparse api; added namespace event support (0.9.8) 23 * 2005-01-23 fl revised iterparse api; added namespace event support (0.9.8)
26 * 2005-01-26 fl added VERSION module property (cElementTree 1.0) 24 * 2005-01-26 fl added VERSION module property (cElementTree 1.0)
27 * 2005-01-28 fl added remove method (1.0.1) 25 * 2005-01-28 fl added remove method (1.0.1)
28 * 2005-03-01 fl added iselement function; fixed makeelement aliasing (1.0.2) 26 * 2005-03-01 fl added iselement function; fixed makeelement aliasing (1.0.2)
29 * 2005-03-13 fl export Comment and ProcessingInstruction/PI helpers 27 * 2005-03-13 fl export Comment and ProcessingInstruction/PI helpers
30 * 2005-03-26 fl added Comment and PI support to XMLParser 28 * 2005-03-26 fl added Comment and PI support to XMLParser
31 * 2005-03-27 fl event optimizations; complain about bogus events 29 * 2005-03-27 fl event optimizations; complain about bogus events
32 * 2005-08-08 fl fixed read error handling in parse 30 * 2005-08-08 fl fixed read error handling in parse
33 * 2005-08-11 fl added runtime test for copy workaround (1.0.3) 31 * 2005-08-11 fl added runtime test for copy workaround (1.0.3)
34 * 2005-12-13 fl added expat_capi support (for xml.etree) (1.0.4) 32 * 2005-12-13 fl added expat_capi support (for xml.etree) (1.0.4)
35 * 2005-12-16 fl added support for non-standard encodings 33 * 2005-12-16 fl added support for non-standard encodings
36 * 2006-03-08 fl fixed a couple of potential null-refs and leaks 34 * 2006-03-08 fl fixed a couple of potential null-refs and leaks
37 * 2006-03-12 fl merge in 2.5 ssize_t changes 35 * 2006-03-12 fl merge in 2.5 ssize_t changes
36 * 2007-08-25 fl call custom builder's close method from XMLParser
37 * 2007-08-31 fl added iter, extend from ET 1.3
38 * 2007-09-01 fl fixed ParseError exception, setslice source type, etc
39 * 2007-09-03 fl fixed handling of negative insert indexes
40 * 2007-09-04 fl added itertext from ET 1.3
41 * 2007-09-06 fl added position attribute to ParseError exception
42 * 2008-06-06 fl delay error reporting in iterparse (from Hrvoje Niksic)
43 * 2009-01-10 fl added experimental CAPI interface
38 * 44 *
39 * Copyright (c) 1999-2006 by Secret Labs AB. All rights reserved. 45 * Copyright (c) 1999-2009 by Secret Labs AB. All rights reserved.
40 * Copyright (c) 1999-2006 by Fredrik Lundh. 46 * Copyright (c) 1999-2009 by Fredrik Lundh.
41 * 47 *
42 * info@pythonware.com 48 * info@pythonware.com
43 * http://www.pythonware.com 49 * http://www.pythonware.com
44 */ 50 */
45 51
46 /* Licensed to PSF under a Contributor Agreement. */ 52 /* Licensed to PSF under a Contributor Agreement. */
47 /* See http://www.python.org/2.4/license for licensing details. */ 53 /* See http://www.python.org/psf/license for licensing details. */
48 54
49 #include "Python.h" 55 #include "Python.h"
50 56
51 #define VERSION "1.0.6" 57 #include "celementtree.h" /* CAPI stuff */
58
59 #define VERSION "1.0.6a2"
52 60
53 /* -------------------------------------------------------------------- */ 61 /* -------------------------------------------------------------------- */
54 /* configuration */ 62 /* configuration */
55 63
56 /* Leave defined to include the expat-based XMLParser type */ 64 /* Leave defined to include the expat-based XMLParser type */
57 #define USE_EXPAT 65 #define USE_EXPAT
58 66
59 /* Define to to all expat calls via pyexpat's embedded expat library */ 67 /* Define to do all expat calls via pyexpat's embedded expat library */
60 /* #define USE_PYEXPAT_CAPI */ 68 /* #define USE_PYEXPAT_CAPI */
61 69
62 /* An element can hold this many children without extra memory 70 /* An element can hold this many children without extra memory
63 allocations. */ 71 allocations. */
64 #define STATIC_CHILDREN 4 72 #define STATIC_CHILDREN 4
65 73
66 /* For best performance, chose a value so that 80-90% of all nodes 74 /* For best performance, chose a value so that 80-90% of all nodes
67 have no more than the given number of children. Set this to zero 75 have no more than the given number of children. Set this to zero
68 to minimize the size of the element structure itself (this only 76 to minimize the size of the element structure itself (this only
69 helps if you have lots of leaf nodes with attributes). */ 77 helps if you have lots of leaf nodes with attributes). */
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 124
117 /* macros used to store 'join' flags in string object pointers. note 125 /* macros used to store 'join' flags in string object pointers. note
118 that all use of text and tail as object pointers must be wrapped in 126 that all use of text and tail as object pointers must be wrapped in
119 JOIN_OBJ. see comments in the ElementObject definition for more 127 JOIN_OBJ. see comments in the ElementObject definition for more
120 info. */ 128 info. */
121 #define JOIN_GET(p) ((Py_uintptr_t) (p) & 1) 129 #define JOIN_GET(p) ((Py_uintptr_t) (p) & 1)
122 #define JOIN_SET(p, flag) ((void*) ((Py_uintptr_t) (JOIN_OBJ(p)) | (flag))) 130 #define JOIN_SET(p, flag) ((void*) ((Py_uintptr_t) (JOIN_OBJ(p)) | (flag)))
123 #define JOIN_OBJ(p) ((PyObject*) ((Py_uintptr_t) (p) & ~1)) 131 #define JOIN_OBJ(p) ((PyObject*) ((Py_uintptr_t) (p) & ~1))
124 132
125 /* glue functions (see the init function for details) */ 133 /* glue functions (see the init function for details) */
134 static PyObject* elementtree_parseerror_obj;
126 static PyObject* elementtree_copyelement_obj; 135 static PyObject* elementtree_copyelement_obj;
127 static PyObject* elementtree_deepcopy_obj; 136 static PyObject* elementtree_deepcopy_obj;
128 static PyObject* elementtree_getiterator_obj; 137 static PyObject* elementtree_iter_obj;
138 static PyObject* elementtree_itertext_obj;
129 static PyObject* elementpath_obj; 139 static PyObject* elementpath_obj;
130 140
131 /* helpers */ 141 /* helpers */
132 142
133 LOCAL(PyObject*) 143 LOCAL(PyObject*)
134 deepcopy(PyObject* object, PyObject* memo) 144 deepcopy(PyObject* object, PyObject* memo)
135 { 145 {
136 /* do a deep copy of the given object */ 146 /* do a deep copy of the given object */
137 147
138 PyObject* args; 148 PyObject* args;
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 if (PyDict_CheckExact(attrib) && !PyDict_Size(attrib)) 333 if (PyDict_CheckExact(attrib) && !PyDict_Size(attrib))
324 attrib = Py_None; 334 attrib = Py_None;
325 335
326 self->extra = NULL; 336 self->extra = NULL;
327 337
328 if (attrib != Py_None) { 338 if (attrib != Py_None) {
329 339
330 if (element_new_extra(self, attrib) < 0) { 340 if (element_new_extra(self, attrib) < 0) {
331 PyObject_Del(self); 341 PyObject_Del(self);
332 return NULL; 342 return NULL;
333 » } 343 }
334 344
335 self->extra->length = 0; 345 self->extra->length = 0;
336 self->extra->allocated = STATIC_CHILDREN; 346 self->extra->allocated = STATIC_CHILDREN;
337 self->extra->children = self->extra->_children; 347 self->extra->children = self->extra->_children;
338 348
339 } 349 }
340 350
341 Py_INCREF(tag); 351 Py_INCREF(tag);
342 self->tag = tag; 352 self->tag = tag;
343 353
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 return -1; 422 return -1;
413 423
414 Py_INCREF(element); 424 Py_INCREF(element);
415 self->extra->children[self->extra->length] = element; 425 self->extra->children[self->extra->length] = element;
416 426
417 self->extra->length++; 427 self->extra->length++;
418 428
419 return 0; 429 return 0;
420 } 430 }
421 431
432 static PyObject*
433 element_get_type(void)
434 {
435 /* return borrowed reference to type object */
436
437 return (PyObject*) &Element_Type;
438 }
439
422 LOCAL(PyObject*) 440 LOCAL(PyObject*)
423 element_get_attrib(ElementObject* self) 441 element_get_attrib(ElementObject* self)
424 { 442 {
425 /* return borrowed reference to attrib dictionary */ 443 /* return borrowed reference to attrib dictionary */
426 /* note: this function assumes that the extra section exists */ 444 /* note: this function assumes that the extra section exists */
427 445
428 PyObject* res = self->extra->attrib; 446 PyObject* res = self->extra->attrib;
429 447
430 if (res == Py_None) { 448 if (res == Py_None) {
449 Py_DECREF(res);
431 /* create missing dictionary */ 450 /* create missing dictionary */
432 res = PyDict_New(); 451 res = PyDict_New();
433 if (!res) 452 if (!res)
434 return NULL; 453 return NULL;
435 self->extra->attrib = res; 454 self->extra->attrib = res;
436 } 455 }
437 456
438 return res; 457 return res;
439 } 458 }
440 459
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 } 721 }
703 element->extra->children[i] = child; 722 element->extra->children[i] = child;
704 } 723 }
705 724
706 element->extra->length = self->extra->length; 725 element->extra->length = self->extra->length;
707 ········ 726 ········
708 } 727 }
709 728
710 /* add object to memo dictionary (so deepcopy won't visit it again) */ 729 /* add object to memo dictionary (so deepcopy won't visit it again) */
711 id = PyInt_FromLong((Py_uintptr_t) self); 730 id = PyInt_FromLong((Py_uintptr_t) self);
731 if (!id)
732 goto error;
712 733
713 i = PyDict_SetItem(memo, id, (PyObject*) element); 734 i = PyDict_SetItem(memo, id, (PyObject*) element);
714 735
715 Py_DECREF(id); 736 Py_DECREF(id);
716 737
717 if (i < 0) 738 if (i < 0)
718 goto error; 739 goto error;
719 740
720 return (PyObject*) element; 741 return (PyObject*) element;
721 742
722 error: 743 error:
723 Py_DECREF(element); 744 Py_DECREF(element);
724 return NULL; 745 return NULL;
725 } 746 }
726 747
727 LOCAL(int) 748 LOCAL(int)
728 checkpath(PyObject* tag) 749 checkpath(PyObject* tag)
729 { 750 {
730 Py_ssize_t i; 751 Py_ssize_t i;
731 int check = 1; 752 int check = 1;
732 753
733 /* check if a tag contains an xpath character */ 754 /* check if a tag contains an xpath character */
734 755
735 #define PATHCHAR(ch) (ch == '/' || ch == '*' || ch == '[' || ch == '@') 756 #define PATHCHAR(ch) \
757 (ch == '/' || ch == '*' || ch == '[' || ch == '@' || ch == '.')
736 758
737 #if defined(Py_USING_UNICODE) 759 #if defined(Py_USING_UNICODE)
738 if (PyUnicode_Check(tag)) { 760 if (PyUnicode_Check(tag)) {
739 Py_UNICODE *p = PyUnicode_AS_UNICODE(tag); 761 Py_UNICODE *p = PyUnicode_AS_UNICODE(tag);
740 for (i = 0; i < PyUnicode_GET_SIZE(tag); i++) { 762 for (i = 0; i < PyUnicode_GET_SIZE(tag); i++) {
741 if (p[i] == '{') 763 if (p[i] == '{')
742 check = 0; 764 check = 0;
743 else if (p[i] == '}') 765 else if (p[i] == '}')
744 check = 1; 766 check = 1;
745 else if (check && PATHCHAR(p[i])) 767 else if (check && PATHCHAR(p[i]))
(...skipping 12 matching lines...) Expand all
758 else if (check && PATHCHAR(p[i])) 780 else if (check && PATHCHAR(p[i]))
759 return 1; 781 return 1;
760 } 782 }
761 return 0; 783 return 0;
762 } 784 }
763 785
764 return 1; /* unknown type; might be path expression */ 786 return 1; /* unknown type; might be path expression */
765 } 787 }
766 788
767 static PyObject* 789 static PyObject*
790 element_extend(ElementObject* self, PyObject* args)
791 {
792 PyObject* seq;
793 Py_ssize_t i, seqlen = 0;
794
795 PyObject* seq_in;
796 if (!PyArg_ParseTuple(args, "O:extend", &seq_in))
797 return NULL;
798
799 seq = PySequence_Fast(seq_in, "");
flox 2010/02/12 14:07:23 Don't miss this one, next time...
800 if (!seq)
801 return NULL;
802
803 seqlen = PySequence_Size(seq);
804 for (i = 0; i < seqlen; i++) {
805 PyObject* element = PySequence_Fast_GET_ITEM(seq, i);
806 if (element_add_subelement(self, element) < 0) {
807 Py_DECREF(seq);
808 return NULL;
809 }
810 }
811
812 Py_DECREF(seq);
813
814 Py_RETURN_NONE;
815 }
816
817 static PyObject*
768 element_find(ElementObject* self, PyObject* args) 818 element_find(ElementObject* self, PyObject* args)
769 { 819 {
770 int i; 820 int i;
771 821
772 PyObject* tag; 822 PyObject* tag;
773 if (!PyArg_ParseTuple(args, "O:find", &tag)) 823 if (!PyArg_ParseTuple(args, "O:find", &tag))
774 return NULL; 824 return NULL;
775 825
776 if (checkpath(tag)) 826 if (checkpath(tag))
777 return PyObject_CallMethod( 827 return PyObject_CallMethod(
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 } 875 }
826 876
827 Py_INCREF(default_value); 877 Py_INCREF(default_value);
828 return default_value; 878 return default_value;
829 } 879 }
830 880
831 static PyObject* 881 static PyObject*
832 element_findall(ElementObject* self, PyObject* args) 882 element_findall(ElementObject* self, PyObject* args)
833 { 883 {
834 int i; 884 int i;
835 PyObject* out; 885 PyObject *out, *it;
836 886
837 PyObject* tag; 887 PyObject* tag;
838 if (!PyArg_ParseTuple(args, "O:findall", &tag)) 888 if (!PyArg_ParseTuple(args, "O:findall", &tag))
839 return NULL; 889 return NULL;
840 890
841 if (checkpath(tag)) 891 if (checkpath(tag))
842 return PyObject_CallMethod( 892 return PyObject_CallMethod(
843 elementpath_obj, "findall", "OO", self, tag 893 elementpath_obj, "findall", "OO", self, tag
844 ); 894 );
845 895
846 out = PyList_New(0); 896 out = PyList_New(0);
847 if (!out) 897 if (!out)
848 return NULL; 898 return NULL;
849 899
850 if (!self->extra) 900 if (!self->extra)
851 return out; 901 return out;
852 902
853 for (i = 0; i < self->extra->length; i++) { 903 for (i = 0; i < self->extra->length; i++) {
854 PyObject* item = self->extra->children[i]; 904 PyObject* item = self->extra->children[i];
855 if (Element_CheckExact(item) && 905 if (Element_CheckExact(item) &&
856 PyObject_Compare(((ElementObject*)item)->tag, tag) == 0) { 906 PyObject_Compare(((ElementObject*)item)->tag, tag) == 0) {
857 if (PyList_Append(out, item) < 0) { 907 if (PyList_Append(out, item) < 0) {
858 Py_DECREF(out); 908 Py_DECREF(out);
859 return NULL; 909 return NULL;
860 } 910 }
861 } 911 }
862 } 912 }
863 913
864 return out; 914 it = PyObject_GetIter(out);
915 Py_DECREF(out);
916 if (it == NULL)
917 return NULL;
Antoine Pitrou 2010/02/12 15:27:46 This conditional is quite useless, isn't it?
flox 2010/02/12 16:07:47 indeed, it is ...
918 return it;
865 } 919 }
866 920
867 static PyObject* 921 static PyObject*
868 element_get(ElementObject* self, PyObject* args) 922 element_get(ElementObject* self, PyObject* args)
869 { 923 {
870 PyObject* value; 924 PyObject* value;
871 925
872 PyObject* key; 926 PyObject* key;
873 PyObject* default_value = Py_None; 927 PyObject* default_value = Py_None;
874 if (!PyArg_ParseTuple(args, "O|O:get", &key, &default_value)) 928 if (!PyArg_ParseTuple(args, "O|O:get", &key, &default_value))
(...skipping 30 matching lines...) Expand all
905 for (i = 0; i < self->extra->length; i++) { 959 for (i = 0; i < self->extra->length; i++) {
906 PyObject* item = self->extra->children[i]; 960 PyObject* item = self->extra->children[i];
907 Py_INCREF(item); 961 Py_INCREF(item);
908 PyList_SET_ITEM(list, i, item); 962 PyList_SET_ITEM(list, i, item);
909 } 963 }
910 964
911 return list; 965 return list;
912 } 966 }
913 967
914 static PyObject* 968 static PyObject*
915 element_getiterator(ElementObject* self, PyObject* args) 969 element_iter(ElementObject* self, PyObject* args)
916 { 970 {
917 PyObject* result; 971 PyObject* result;
918 ···· 972 ····
919 PyObject* tag = Py_None; 973 PyObject* tag = Py_None;
920 if (!PyArg_ParseTuple(args, "|O:getiterator", &tag)) 974 if (!PyArg_ParseTuple(args, "|O:iter", &tag))
921 return NULL; 975 return NULL;
922 976
923 if (!elementtree_getiterator_obj) { 977 if (!elementtree_iter_obj) {
924 PyErr_SetString( 978 PyErr_SetString(
925 PyExc_RuntimeError, 979 PyExc_RuntimeError,
926 "getiterator helper not found" 980 "iter helper not found"
927 ); 981 );
928 return NULL; 982 return NULL;
929 } 983 }
930 984
931 args = PyTuple_New(2); 985 args = PyTuple_New(2);
932 if (!args) 986 if (!args)
933 return NULL; 987 return NULL;
934 988
935 Py_INCREF(self); PyTuple_SET_ITEM(args, 0, (PyObject*) self); 989 Py_INCREF(self); PyTuple_SET_ITEM(args, 0, (PyObject*) self);
936 Py_INCREF(tag); PyTuple_SET_ITEM(args, 1, (PyObject*) tag); 990 Py_INCREF(tag); PyTuple_SET_ITEM(args, 1, (PyObject*) tag);
937 991
938 result = PyObject_CallObject(elementtree_getiterator_obj, args); 992 result = PyObject_CallObject(elementtree_iter_obj, args);
939 993
940 Py_DECREF(args); 994 Py_DECREF(args);
941 995
996 return result;
997 }
998
999
1000 static PyObject*
1001 element_itertext(ElementObject* self, PyObject* args)
1002 {
1003 PyObject* result;
1004 ····
1005 if (!PyArg_ParseTuple(args, ":itertext"))
1006 return NULL;
1007
1008 if (!elementtree_itertext_obj) {
1009 PyErr_SetString(
1010 PyExc_RuntimeError,
1011 "itertext helper not found"
1012 );
1013 return NULL;
1014 }
1015
1016 args = PyTuple_New(1);
1017 if (!args)
1018 return NULL;
1019
1020 Py_INCREF(self); PyTuple_SET_ITEM(args, 0, (PyObject*) self);
1021
1022 result = PyObject_CallObject(elementtree_itertext_obj, args);
1023
1024 Py_DECREF(args);
1025
942 return result; 1026 return result;
943 } 1027 }
944 1028
945 static PyObject* 1029 static PyObject*
946 element_getitem(PyObject* self_, Py_ssize_t index) 1030 element_getitem(PyObject* self_, Py_ssize_t index)
947 { 1031 {
948 ElementObject* self = (ElementObject*) self_; 1032 ElementObject* self = (ElementObject*) self_;
949 1033
950 if (!self->extra || index < 0 || index >= self->extra->length) { 1034 if (!self->extra || index < 0 || index >= self->extra->length) {
951 PyErr_SetString( 1035 PyErr_SetString(
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 1083
1000 int index; 1084 int index;
1001 PyObject* element; 1085 PyObject* element;
1002 if (!PyArg_ParseTuple(args, "iO!:insert", &index, 1086 if (!PyArg_ParseTuple(args, "iO!:insert", &index,
1003 &Element_Type, &element)) 1087 &Element_Type, &element))
1004 return NULL; 1088 return NULL;
1005 1089
1006 if (!self->extra) 1090 if (!self->extra)
1007 element_new_extra(self, NULL); 1091 element_new_extra(self, NULL);
1008 1092
1009 if (index < 0) 1093 if (index < 0) {
1010 index = 0; 1094 index += self->extra->length;
1095 if (index < 0)
1096 index = 0;
1097 }
1011 if (index > self->extra->length) 1098 if (index > self->extra->length)
1012 index = self->extra->length; 1099 index = self->extra->length;
1013 1100
1014 if (element_resize(self, 1) < 0) 1101 if (element_resize(self, 1) < 0)
1015 return NULL; 1102 return NULL;
1016 1103
1017 for (i = self->extra->length; i > index; i--) 1104 for (i = self->extra->length; i > index; i--)
1018 self->extra->children[i] = self->extra->children[i-1]; 1105 self->extra->children[i] = self->extra->children[i-1];
1019 1106
1020 Py_INCREF(element); 1107 Py_INCREF(element);
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 if (!attrib) 1268 if (!attrib)
1182 return NULL; 1269 return NULL;
1183 1270
1184 if (PyDict_SetItem(attrib, key, value) < 0) 1271 if (PyDict_SetItem(attrib, key, value) < 0)
1185 return NULL; 1272 return NULL;
1186 1273
1187 Py_RETURN_NONE; 1274 Py_RETURN_NONE;
1188 } 1275 }
1189 1276
1190 static int 1277 static int
1191 element_setslice(PyObject* self_, Py_ssize_t start, Py_ssize_t end, PyObject* it em) 1278 element_setslice(PyObject* self_, Py_ssize_t start, Py_ssize_t end, PyObject* se q_in)
1192 { 1279 {
1193 ElementObject* self = (ElementObject*) self_; 1280 ElementObject* self = (ElementObject*) self_;
1194 Py_ssize_t i, new, old; 1281 Py_ssize_t i, new, old;
1195 PyObject* recycle = NULL; 1282 PyObject* recycle = NULL;
1283 PyObject* seq = NULL;
1196 1284
1197 if (!self->extra) 1285 if (!self->extra)
1198 element_new_extra(self, NULL); 1286 element_new_extra(self, NULL);
1199 1287
1200 /* standard clamping */ 1288 /* standard clamping */
1201 if (start < 0) 1289 if (start < 0)
1202 start = 0; 1290 start = 0;
1203 if (end < 0) 1291 if (end < 0)
1204 end = 0; 1292 end = 0;
1205 if (end > self->extra->length) 1293 if (end > self->extra->length)
1206 end = self->extra->length; 1294 end = self->extra->length;
1207 if (start > end) 1295 if (start > end)
1208 start = end; 1296 start = end;
1209 1297
1210 old = end - start; 1298 old = end - start;
1211 1299
1212 if (item == NULL) 1300 if (seq_in == NULL)
1213 new = 0; 1301 new = 0;
1214 else if (PyList_CheckExact(item)) { 1302 else {
1215 new = PyList_GET_SIZE(item); 1303 seq = PySequence_Fast(seq_in, "can only assign an iterable");
flox 2010/02/12 14:07:23 2nd argument is useless and can be reverted to emp
Antoine Pitrou 2010/02/12 15:27:46 Certainly, yes.
1216 } else { 1304 if (!seq) {
1217 /* FIXME: support arbitrary sequences? */ 1305 PyErr_Format(
1218 PyErr_Format( 1306 PyExc_TypeError,
1219 PyExc_TypeError, 1307 "expected sequence, not \"%.200s\"", Py_TYPE(seq_in)->tp_name
1220 "expected list, not \"%.200s\"", Py_TYPE(item)->tp_name 1308 );
1221 ); 1309 return -1;
1222 return -1; 1310 }
1311 new = PySequence_Size(seq);
1223 } 1312 }
1224 1313
1225 if (old > 0) { 1314 if (old > 0) {
1226 /* to avoid recursive calls to this method (via decref), move 1315 /* to avoid recursive calls to this method (via decref), move
1227 old items to the recycle bin here, and get rid of them when 1316 old items to the recycle bin here, and get rid of them when
1228 we're done modifying the element */ 1317 we're done modifying the element */
1229 recycle = PyList_New(old); 1318 recycle = PyList_New(old);
1230 for (i = 0; i < old; i++) 1319 for (i = 0; i < old; i++)
1231 PyList_SET_ITEM(recycle, i, self->extra->children[i + start]); 1320 PyList_SET_ITEM(recycle, i, self->extra->children[i + start]);
1232 } 1321 }
1233 1322
1234 if (new < old) { 1323 if (new < old) {
1235 /* delete slice */ 1324 /* delete slice */
1236 for (i = end; i < self->extra->length; i++) 1325 for (i = end; i < self->extra->length; i++)
1237 self->extra->children[i + new - old] = self->extra->children[i]; 1326 self->extra->children[i + new - old] = self->extra->children[i];
1238 } else if (new > old) { 1327 } else if (new > old) {
1239 /* insert slice */ 1328 /* insert slice */
1240 if (element_resize(self, new - old) < 0) 1329 if (element_resize(self, new - old) < 0) {
1330 if (seq)
1331 Py_DECREF(seq);
1241 return -1; 1332 return -1;
1333 }
1242 for (i = self->extra->length-1; i >= end; i--) 1334 for (i = self->extra->length-1; i >= end; i--)
1243 self->extra->children[i + new - old] = self->extra->children[i]; 1335 self->extra->children[i + new - old] = self->extra->children[i];
1244 } 1336 }
1245 1337
1246 /* replace the slice */ 1338 /* replace the slice */
1247 for (i = 0; i < new; i++) { 1339 for (i = 0; i < new; i++) {
1248 PyObject* element = PyList_GET_ITEM(item, i); 1340 PyObject* element = PySequence_Fast_GET_ITEM(seq, i);
1249 Py_INCREF(element); 1341 Py_INCREF(element);
1250 self->extra->children[i + start] = element; 1342 self->extra->children[i + start] = element;
1251 } 1343 }
1252 1344
1253 self->extra->length += new - old; 1345 self->extra->length += new - old;
1254 1346
1347 if (seq)
1348 Py_DECREF(seq);
1349
1255 /* discard the recycle bin, and everything in it */ 1350 /* discard the recycle bin, and everything in it */
1256 Py_XDECREF(recycle); 1351 Py_XDECREF(recycle);
1257 1352
1258 return 0; 1353 return 0;
1259 } 1354 }
1260 1355
1261 static int 1356 static int
1262 element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) 1357 element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
1263 { 1358 {
1264 ElementObject* self = (ElementObject*) self_; 1359 ElementObject* self = (ElementObject*) self_;
(...skipping 16 matching lines...) Expand all
1281 self->extra->length--; 1376 self->extra->length--;
1282 for (i = index; i < self->extra->length; i++) 1377 for (i = index; i < self->extra->length; i++)
1283 self->extra->children[i] = self->extra->children[i+1]; 1378 self->extra->children[i] = self->extra->children[i+1];
1284 } 1379 }
1285 1380
1286 Py_DECREF(old); 1381 Py_DECREF(old);
1287 1382
1288 return 0; 1383 return 0;
1289 } 1384 }
1290 1385
1386 static PyObject*
1387 element_subscr(PyObject* self_, PyObject* item)
1388 {
1389 ElementObject* self = (ElementObject*) self_;
1390
1391 if (PyIndex_Check(item)) {
1392 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1393 if (i==-1 && PyErr_Occurred()) {
1394 return NULL;
1395 }
1396 if (i < 0 && self->extra)
1397 i += self->extra->length;
1398 return element_getitem(self_, i);
1399 }
1400 else if (PySlice_Check(item)) {
1401 Py_ssize_t start, stop, step, slicelen, cur, i;
1402 PyObject* list;
1403
1404 if (!self->extra)
1405 return PyList_New(0);
1406
1407 if (PySlice_GetIndicesEx((PySliceObject *)item,
1408 self->extra->length,
1409 &start, &stop, &step, &slicelen) < 0) {
1410 return NULL;
1411 }
1412
1413 if (slicelen <= 0)
1414 return PyList_New(0);
1415 else {
1416 list = PyList_New(slicelen);
1417 if (!list)
1418 return NULL;
1419
1420 for (cur = start, i = 0; i < slicelen;
1421 cur += step, i++) {
1422 PyObject* item = self->extra->children[cur];
1423 Py_INCREF(item);
1424 PyList_SET_ITEM(list, i, item);
1425 }
1426
1427 return list;
1428 }
1429 }
1430 else {
1431 PyErr_SetString(PyExc_TypeError,
1432 "element indices must be integers");
1433 return NULL;
1434 }
1435 }
1436
1437 static int
1438 element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
1439 {
1440 ElementObject* self = (ElementObject*) self_;
1441
1442 if (PyIndex_Check(item)) {
1443 Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
1444
1445 if (i==-1 && PyErr_Occurred()) {
1446 return -1;
1447 }
1448 if (i < 0 && self->extra)
1449 i += self->extra->length;
1450 return element_setitem(self_, i, value);
1451 }
1452 else if (PySlice_Check(item)) {
1453 Py_ssize_t start, stop, step, slicelen, newlen, cur, i;
1454
1455 PyObject* recycle = NULL;
1456 PyObject* seq = NULL;
1457
1458 if (!self->extra)
1459 element_new_extra(self, NULL);
1460
1461 if (PySlice_GetIndicesEx((PySliceObject *)item,
1462 self->extra->length,
1463 &start, &stop, &step, &slicelen) < 0) {
1464 return -1;
1465 }
1466
1467 if (value == NULL)
1468 newlen = 0;
1469 else {
1470 seq = PySequence_Fast(value, "");
1471 if (!seq) {
1472 PyErr_Format(
1473 PyExc_TypeError,
1474 "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name
1475 );
1476 return -1;
1477 }
1478 newlen = PySequence_Size(seq);
1479 }
1480
1481 if (step != 1 && newlen != slicelen)
1482 {
1483 PyErr_Format(PyExc_ValueError,
1484 "attempt to assign sequence of size %zd "
1485 "to extended slice of size %zd",
1486 newlen, slicelen
1487 );
1488 return -1;
1489 }
1490
1491
1492 /* Resize before creating the recycle bin, to prevent refleaks. */
1493 if (newlen > slicelen) {
1494 if (element_resize(self, newlen - slicelen) < 0) {
1495 if (seq)
1496 Py_DECREF(seq);
1497 return -1;
1498 }
1499 }
1500
1501 if (slicelen > 0) {
1502 /* to avoid recursive calls to this method (via decref), move
1503 old items to the recycle bin here, and get rid of them when
1504 we're done modifying the element */
1505 recycle = PyList_New(slicelen);
1506 if (!recycle) {
1507 if (seq)
1508 Py_DECREF(seq);
1509 return -1;
1510 }
1511 for (cur = start, i = 0; i < slicelen;
1512 cur += step, i++)
1513 PyList_SET_ITEM(recycle, i, self->extra->children[cur]);
1514 }
1515
1516 if (newlen < slicelen) {
1517 /* delete slice */
1518 for (i = stop; i < self->extra->length; i++)
1519 self->extra->children[i + newlen - slicelen] = self->extra->chil dren[i];
1520 } else if (newlen > slicelen) {
1521 /* insert slice */
1522 for (i = self->extra->length-1; i >= stop; i--)
1523 self->extra->children[i + newlen - slicelen] = self->extra->chil dren[i];
1524 }
1525
1526 /* replace the slice */
1527 for (cur = start, i = 0; i < newlen;
1528 cur += step, i++) {
1529 PyObject* element = PySequence_Fast_GET_ITEM(seq, i);
1530 Py_INCREF(element);
1531 self->extra->children[cur] = element;
1532 }
1533
1534 self->extra->length += newlen - slicelen;
1535
1536 if (seq)
1537 Py_DECREF(seq);
1538
1539 /* discard the recycle bin, and everything in it */
1540 Py_XDECREF(recycle);
1541
1542 return 0;
1543 }
1544 else {
1545 PyErr_SetString(PyExc_TypeError,
1546 "element indices must be integers");
1547 return -1;
1548 }
1549 }
1550
1291 static PyMethodDef element_methods[] = { 1551 static PyMethodDef element_methods[] = {
1292 1552
1293 {"clear", (PyCFunction) element_clear, METH_VARARGS}, 1553 {"clear", (PyCFunction) element_clear, METH_VARARGS},
1294 1554
1295 {"get", (PyCFunction) element_get, METH_VARARGS}, 1555 {"get", (PyCFunction) element_get, METH_VARARGS},
1296 {"set", (PyCFunction) element_set, METH_VARARGS}, 1556 {"set", (PyCFunction) element_set, METH_VARARGS},
1297 1557
1298 {"find", (PyCFunction) element_find, METH_VARARGS}, 1558 {"find", (PyCFunction) element_find, METH_VARARGS},
1299 {"findtext", (PyCFunction) element_findtext, METH_VARARGS}, 1559 {"findtext", (PyCFunction) element_findtext, METH_VARARGS},
1300 {"findall", (PyCFunction) element_findall, METH_VARARGS}, 1560 {"findall", (PyCFunction) element_findall, METH_VARARGS},
1301 1561
1302 {"append", (PyCFunction) element_append, METH_VARARGS}, 1562 {"append", (PyCFunction) element_append, METH_VARARGS},
1563 {"extend", (PyCFunction) element_extend, METH_VARARGS},
1303 {"insert", (PyCFunction) element_insert, METH_VARARGS}, 1564 {"insert", (PyCFunction) element_insert, METH_VARARGS},
1304 {"remove", (PyCFunction) element_remove, METH_VARARGS}, 1565 {"remove", (PyCFunction) element_remove, METH_VARARGS},
1305 1566
1306 {"getiterator", (PyCFunction) element_getiterator, METH_VARARGS}, 1567 {"iter", (PyCFunction) element_iter, METH_VARARGS},
1568 {"itertext", (PyCFunction) element_itertext, METH_VARARGS},
1569
1570 {"getiterator", (PyCFunction) element_iter, METH_VARARGS},
1307 {"getchildren", (PyCFunction) element_getchildren, METH_VARARGS}, 1571 {"getchildren", (PyCFunction) element_getchildren, METH_VARARGS},
1308 1572
1309 {"items", (PyCFunction) element_items, METH_VARARGS}, 1573 {"items", (PyCFunction) element_items, METH_VARARGS},
1310 {"keys", (PyCFunction) element_keys, METH_VARARGS}, 1574 {"keys", (PyCFunction) element_keys, METH_VARARGS},
1311 1575
1312 {"makeelement", (PyCFunction) element_makeelement, METH_VARARGS}, 1576 {"makeelement", (PyCFunction) element_makeelement, METH_VARARGS},
1313 1577
1314 {"__copy__", (PyCFunction) element_copy, METH_VARARGS}, 1578 {"__copy__", (PyCFunction) element_copy, METH_VARARGS},
1315 {"__deepcopy__", (PyCFunction) element_deepcopy, METH_VARARGS}, 1579 {"__deepcopy__", (PyCFunction) element_deepcopy, METH_VARARGS},
1316 1580
(...skipping 12 matching lines...) Expand all
1329 {NULL, NULL} 1593 {NULL, NULL}
1330 }; 1594 };
1331 1595
1332 static PyObject*·· 1596 static PyObject*··
1333 element_getattr(ElementObject* self, char* name) 1597 element_getattr(ElementObject* self, char* name)
1334 { 1598 {
1335 PyObject* res; 1599 PyObject* res;
1336 1600
1337 res = Py_FindMethod(element_methods, (PyObject*) self, name); 1601 res = Py_FindMethod(element_methods, (PyObject*) self, name);
1338 if (res) 1602 if (res)
1339 » return res; 1603 return res;
1340 1604
1341 PyErr_Clear(); 1605 PyErr_Clear();
1342 1606
1343 if (strcmp(name, "tag") == 0) 1607 if (strcmp(name, "tag") == 0)
1344 » res = self->tag; 1608 res = self->tag;
1345 else if (strcmp(name, "text") == 0) 1609 else if (strcmp(name, "text") == 0)
1346 res = element_get_text(self); 1610 res = element_get_text(self);
1347 else if (strcmp(name, "tail") == 0) { 1611 else if (strcmp(name, "tail") == 0) {
1348 res = element_get_tail(self); 1612 res = element_get_tail(self);
1349 } else if (strcmp(name, "attrib") == 0) { 1613 } else if (strcmp(name, "attrib") == 0) {
1350 if (!self->extra) 1614 if (!self->extra)
1351 element_new_extra(self, NULL); 1615 element_new_extra(self, NULL);
1352 » res = element_get_attrib(self); 1616 res = element_get_attrib(self);
1353 } else { 1617 } else {
1354 PyErr_SetString(PyExc_AttributeError, name); 1618 PyErr_SetString(PyExc_AttributeError, name);
1355 return NULL; 1619 return NULL;
1356 } 1620 }
1357 1621
1358 if (!res) 1622 if (!res)
1359 return NULL; 1623 return NULL;
1360 1624
1361 Py_INCREF(res); 1625 Py_INCREF(res);
1362 return res; 1626 return res;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 } 1661 }
1398 1662
1399 return 0; 1663 return 0;
1400 } 1664 }
1401 1665
1402 static PySequenceMethods element_as_sequence = { 1666 static PySequenceMethods element_as_sequence = {
1403 (lenfunc) element_length, 1667 (lenfunc) element_length,
1404 0, /* sq_concat */ 1668 0, /* sq_concat */
1405 0, /* sq_repeat */ 1669 0, /* sq_repeat */
1406 element_getitem, 1670 element_getitem,
1407 element_getslice, 1671 0,
1408 element_setitem, 1672 element_setitem,
1409 element_setslice, 1673 0,
Antoine Pitrou 2010/02/12 15:27:46 If element_setslice and element_getslice aren't us
flox 2010/02/12 16:07:47 * element_setslice is unused * element_getslice i
1674 };
1675
1676 static PyMappingMethods element_as_mapping = {
1677 (lenfunc) element_length,
1678 (binaryfunc) element_subscr,
1679 (objobjargproc) element_ass_subscr
1410 }; 1680 };
1411 1681
1412 statichere PyTypeObject Element_Type = { 1682 statichere PyTypeObject Element_Type = {
1413 PyObject_HEAD_INIT(NULL) 1683 PyObject_HEAD_INIT(NULL)
1414 0, "Element", sizeof(ElementObject), 0, 1684 0, "Element", sizeof(ElementObject), 0,
1415 /* methods */ 1685 /* methods */
1416 (destructor)element_dealloc, /* tp_dealloc */ 1686 (destructor)element_dealloc, /* tp_dealloc */
1417 0, /* tp_print */ 1687 0, /* tp_print */
1418 (getattrfunc)element_getattr, /* tp_getattr */ 1688 (getattrfunc)element_getattr, /* tp_getattr */
1419 (setattrfunc)element_setattr, /* tp_setattr */ 1689 (setattrfunc)element_setattr, /* tp_setattr */
1420 0, /* tp_compare */ 1690 0, /* tp_compare */
1421 (reprfunc)element_repr, /* tp_repr */ 1691 (reprfunc)element_repr, /* tp_repr */
1422 0, /* tp_as_number */ 1692 0, /* tp_as_number */
1423 &element_as_sequence, /* tp_as_sequence */ 1693 &element_as_sequence, /* tp_as_sequence */
1694 &element_as_mapping, /* tp_as_mapping */
1424 }; 1695 };
1425 1696
1697 /* -------------------------------------------------------------------- */
1698 /* CAPI interface */
1699
1700 static int
1701 element_capi_assert(PyObject* elem)
1702 {
1703 if (Element_CheckExact(elem))
1704 return 0;
1705 PyErr_Format(
1706 PyExc_TypeError,
1707 "expected cElementTree.Element, not \"%.200s\"",
1708 elem->ob_type->tp_name
1709 );
1710 return -1;
1711 }
1712
1713 static PyObject*
1714 element_capi_getitem(PyObject* self, int index)
1715 {
1716 ElementObject* elem = (ElementObject*) self;
1717
1718 if (!elem->extra || index < 0 || index >= elem->extra->length)
1719 Py_RETURN_NONE;
1720
1721 Py_INCREF(elem->extra->children[index]);
1722 return elem->extra->children[index];
1723 }
1724
1725 static int
1726 element_capi_snapshot(PyObject* self, struct cElementTree_Snapshot* snapshot,
1727 int mode)
1728 {
1729 ElementObject* elem = (ElementObject*) self;
1730
1731 snapshot->tag = elem->tag;
1732 Py_INCREF(snapshot->tag);
1733
1734 snapshot->text = element_get_text(elem);
1735 Py_INCREF(snapshot->text);
1736
1737 snapshot->tail = element_get_tail(elem);
1738 Py_INCREF(snapshot->tail);
1739
1740 if (elem->extra)
1741 snapshot->attrib = element_get_attrib(elem);
1742 else
1743 snapshot->attrib = Py_None;
1744 Py_INCREF(snapshot->attrib);
1745
1746 if (!mode)
1747 return 0;
1748
1749 if (elem->extra) {
1750 snapshot->children = element_getslice(
1751 (PyObject*) elem, 0, elem->extra->length
1752 );
1753 /* FIXME: clean up if slice fails */
1754 } else {
1755 snapshot->children = Py_None;
1756 Py_INCREF(snapshot->children);
1757 }
1758 ········
1759 return 0;
1760 }
1761
1426 /* ==================================================================== */ 1762 /* ==================================================================== */
1427 /* the tree builder type */ 1763 /* the tree builder type */
1428 1764
1429 typedef struct { 1765 typedef struct {
1430 PyObject_HEAD 1766 PyObject_HEAD
1431 1767
1432 PyObject* root; /* root node (first created node) */ 1768 PyObject* root; /* root node (first created node) */
1433 1769
1434 ElementObject* this; /* current node */ 1770 ElementObject* this; /* current node */
1435 ElementObject* last; /* most recently created node */ 1771 ElementObject* last; /* most recently created node */
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 return NULL; 1887 return NULL;
1552 1888
1553 this = (PyObject*) self->this; 1889 this = (PyObject*) self->this;
1554 1890
1555 if (this != Py_None) { 1891 if (this != Py_None) {
1556 if (element_add_subelement((ElementObject*) this, node) < 0) 1892 if (element_add_subelement((ElementObject*) this, node) < 0)
1557 goto error; 1893 goto error;
1558 } else { 1894 } else {
1559 if (self->root) { 1895 if (self->root) {
1560 PyErr_SetString( 1896 PyErr_SetString(
1561 PyExc_SyntaxError, 1897 elementtree_parseerror_obj,
1562 "multiple elements on top level" 1898 "multiple elements on top level"
1563 ); 1899 );
1564 goto error; 1900 goto error;
1565 } 1901 }
1566 Py_INCREF(node); 1902 Py_INCREF(node);
1567 self->root = node; 1903 self->root = node;
1568 } 1904 }
1569 1905
1570 if (self->index < PyList_GET_SIZE(self->stack)) { 1906 if (self->index < PyList_GET_SIZE(self->stack)) {
1571 if (PyList_SetItem(self->stack, self->index, this) < 0) 1907 if (PyList_SetItem(self->stack, self->index, this) < 0)
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 PyObject_HEAD 2186 PyObject_HEAD
1851 2187
1852 XML_Parser parser; 2188 XML_Parser parser;
1853 2189
1854 PyObject* target; 2190 PyObject* target;
1855 PyObject* entity; 2191 PyObject* entity;
1856 2192
1857 PyObject* names; 2193 PyObject* names;
1858 2194
1859 PyObject* handle_xml; 2195 PyObject* handle_xml;
2196
1860 PyObject* handle_start; 2197 PyObject* handle_start;
1861 PyObject* handle_data; 2198 PyObject* handle_data;
1862 PyObject* handle_end; 2199 PyObject* handle_end;
1863 2200
1864 PyObject* handle_comment; 2201 PyObject* handle_comment;
1865 PyObject* handle_pi; 2202 PyObject* handle_pi;
1866 2203
2204 PyObject* handle_close;
2205
1867 } XMLParserObject; 2206 } XMLParserObject;
1868 2207
1869 staticforward PyTypeObject XMLParser_Type; 2208 staticforward PyTypeObject XMLParser_Type;
1870 2209
1871 /* helpers */ 2210 /* helpers */
1872 2211
1873 #if defined(Py_USING_UNICODE) 2212 #if defined(Py_USING_UNICODE)
1874 LOCAL(int) 2213 LOCAL(int)
1875 checkstring(const char* string, int size) 2214 checkstring(const char* string, int size)
1876 { 2215 {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1964 Py_DECREF(key); 2303 Py_DECREF(key);
1965 Py_DECREF(value); 2304 Py_DECREF(value);
1966 return NULL; 2305 return NULL;
1967 } 2306 }
1968 } 2307 }
1969 2308
1970 Py_DECREF(key); 2309 Py_DECREF(key);
1971 return value; 2310 return value;
1972 } 2311 }
1973 2312
2313 static void
2314 expat_set_error(const char* message, int line, int column)
2315 {
2316 PyObject *error;
2317 PyObject *position;
2318 char buffer[256];
2319
2320 sprintf(buffer, "%s: line %d, column %d", message, line, column);
2321
2322 error = PyObject_CallFunction(elementtree_parseerror_obj, "s", buffer);
2323 if (!error)
2324 return;
2325
2326 /* add position attribute */
2327 position = Py_BuildValue("(ii)", line, column);
2328 if (!position) {
2329 Py_DECREF(error);
2330 return;
2331 }
2332 if (PyObject_SetAttrString(error, "position", position) == -1) {
2333 Py_DECREF(error);
2334 Py_DECREF(position);
2335 return;
2336 }
2337 Py_DECREF(position);
2338
2339 PyErr_SetObject(elementtree_parseerror_obj, error);
2340 Py_DECREF(error);
2341 }
2342
1974 /* -------------------------------------------------------------------- */ 2343 /* -------------------------------------------------------------------- */
1975 /* handlers */ 2344 /* handlers */
1976 2345
1977 static void 2346 static void
1978 expat_default_handler(XMLParserObject* self, const XML_Char* data_in, 2347 expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
1979 int data_len) 2348 int data_len)
1980 { 2349 {
1981 PyObject* key; 2350 PyObject* key;
1982 PyObject* value; 2351 PyObject* value;
1983 PyObject* res; 2352 PyObject* res;
(...skipping 10 matching lines...) Expand all
1994 if (value) { 2363 if (value) {
1995 if (TreeBuilder_CheckExact(self->target)) 2364 if (TreeBuilder_CheckExact(self->target))
1996 res = treebuilder_handle_data( 2365 res = treebuilder_handle_data(
1997 (TreeBuilderObject*) self->target, value 2366 (TreeBuilderObject*) self->target, value
1998 ); 2367 );
1999 else if (self->handle_data) 2368 else if (self->handle_data)
2000 res = PyObject_CallFunction(self->handle_data, "O", value); 2369 res = PyObject_CallFunction(self->handle_data, "O", value);
2001 else 2370 else
2002 res = NULL; 2371 res = NULL;
2003 Py_XDECREF(res); 2372 Py_XDECREF(res);
2004 } else { 2373 } else if (!PyErr_Occurred()) {
2005 PyErr_Format( 2374 /* Report the first error, not the last */
2006 PyExc_SyntaxError, "undefined entity &%s;: line %ld, column %ld", 2375 char message[128];
2007 PyString_AS_STRING(key), 2376 sprintf(message, "undefined entity &%.100s;", PyString_AS_STRING(key));
2377 expat_set_error(
2378 message,·
2008 EXPAT(GetErrorLineNumber)(self->parser), 2379 EXPAT(GetErrorLineNumber)(self->parser),
2009 EXPAT(GetErrorColumnNumber)(self->parser) 2380 EXPAT(GetErrorColumnNumber)(self->parser)
2010 ); 2381 );
2011 } 2382 }
2012 2383
2013 Py_DECREF(key); 2384 Py_DECREF(key);
2014 } 2385 }
2015 2386
2016 static void 2387 static void
2017 expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, 2388 expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2052 } 2423 }
2053 } else { 2424 } else {
2054 Py_INCREF(Py_None); 2425 Py_INCREF(Py_None);
2055 attrib = Py_None; 2426 attrib = Py_None;
2056 } 2427 }
2057 2428
2058 if (TreeBuilder_CheckExact(self->target)) 2429 if (TreeBuilder_CheckExact(self->target))
2059 /* shortcut */ 2430 /* shortcut */
2060 res = treebuilder_handle_start((TreeBuilderObject*) self->target, 2431 res = treebuilder_handle_start((TreeBuilderObject*) self->target,
2061 tag, attrib); 2432 tag, attrib);
2062 else if (self->handle_start) 2433 else if (self->handle_start) {
2434 if (attrib == Py_None) {
2435 Py_DECREF(attrib);
2436 attrib = PyDict_New();
2437 if (!attrib)
2438 return;
2439 }
2063 res = PyObject_CallFunction(self->handle_start, "OO", tag, attrib); 2440 res = PyObject_CallFunction(self->handle_start, "OO", tag, attrib);
2064 else 2441 } else
2065 res = NULL; 2442 res = NULL;
2066 2443
2067 Py_DECREF(tag); 2444 Py_DECREF(tag);
2068 Py_DECREF(attrib); 2445 Py_DECREF(attrib);
2069 2446
2070 Py_XDECREF(res); 2447 Py_XDECREF(res);
2071 } 2448 }
2072 2449
2073 static void 2450 static void
2074 expat_data_handler(XMLParserObject* self, const XML_Char* data_in, 2451 expat_data_handler(XMLParserObject* self, const XML_Char* data_in,
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2193 return XML_STATUS_ERROR; 2570 return XML_STATUS_ERROR;
2194 2571
2195 if (PyUnicode_GET_SIZE(u) != 256) { 2572 if (PyUnicode_GET_SIZE(u) != 256) {
2196 Py_DECREF(u); 2573 Py_DECREF(u);
2197 return XML_STATUS_ERROR; 2574 return XML_STATUS_ERROR;
2198 } 2575 }
2199 2576
2200 p = PyUnicode_AS_UNICODE(u); 2577 p = PyUnicode_AS_UNICODE(u);
2201 2578
2202 for (i = 0; i < 256; i++) { 2579 for (i = 0; i < 256; i++) {
2203 » if (p[i] != Py_UNICODE_REPLACEMENT_CHARACTER) 2580 if (p[i] != Py_UNICODE_REPLACEMENT_CHARACTER)
2204 » info->map[i] = p[i]; 2581 info->map[i] = p[i];
2205 else 2582 else
2206 » info->map[i] = -1; 2583 info->map[i] = -1;
2207 } 2584 }
2208 2585
2209 Py_DECREF(u); 2586 Py_DECREF(u);
2210 2587
2211 return XML_STATUS_OK; 2588 return XML_STATUS_OK;
2212 } 2589 }
2213 #endif 2590 #endif
2214 2591
2215 /* -------------------------------------------------------------------- */ 2592 /* -------------------------------------------------------------------- */
2216 /* constructor and destructor */ 2593 /* constructor and destructor */
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2281 } else 2658 } else
2282 Py_INCREF(target); 2659 Py_INCREF(target);
2283 self->target = target; 2660 self->target = target;
2284 2661
2285 self->handle_xml = PyObject_GetAttrString(target, "xml"); 2662 self->handle_xml = PyObject_GetAttrString(target, "xml");
2286 self->handle_start = PyObject_GetAttrString(target, "start"); 2663 self->handle_start = PyObject_GetAttrString(target, "start");
2287 self->handle_data = PyObject_GetAttrString(target, "data"); 2664 self->handle_data = PyObject_GetAttrString(target, "data");
2288 self->handle_end = PyObject_GetAttrString(target, "end"); 2665 self->handle_end = PyObject_GetAttrString(target, "end");
2289 self->handle_comment = PyObject_GetAttrString(target, "comment"); 2666 self->handle_comment = PyObject_GetAttrString(target, "comment");
2290 self->handle_pi = PyObject_GetAttrString(target, "pi"); 2667 self->handle_pi = PyObject_GetAttrString(target, "pi");
2668 self->handle_close = PyObject_GetAttrString(target, "close");
2291 2669
2292 PyErr_Clear(); 2670 PyErr_Clear();
2293 2671
2294 /* configure parser */ 2672 /* configure parser */
2295 EXPAT(SetUserData)(self->parser, self); 2673 EXPAT(SetUserData)(self->parser, self);
2296 EXPAT(SetElementHandler)( 2674 EXPAT(SetElementHandler)(
2297 self->parser, 2675 self->parser,
2298 (XML_StartElementHandler) expat_start_handler, 2676 (XML_StartElementHandler) expat_start_handler,
2299 (XML_EndElementHandler) expat_end_handler 2677 (XML_EndElementHandler) expat_end_handler
2300 ); 2678 );
(...skipping 25 matching lines...) Expand all
2326 ALLOC(sizeof(XMLParserObject), "create expatparser"); 2704 ALLOC(sizeof(XMLParserObject), "create expatparser");
2327 2705
2328 return (PyObject*) self; 2706 return (PyObject*) self;
2329 } 2707 }
2330 2708
2331 static void 2709 static void
2332 xmlparser_dealloc(XMLParserObject* self) 2710 xmlparser_dealloc(XMLParserObject* self)
2333 { 2711 {
2334 EXPAT(ParserFree)(self->parser); 2712 EXPAT(ParserFree)(self->parser);
2335 2713
2714 Py_XDECREF(self->handle_close);
2336 Py_XDECREF(self->handle_pi); 2715 Py_XDECREF(self->handle_pi);
2337 Py_XDECREF(self->handle_comment); 2716 Py_XDECREF(self->handle_comment);
2338 Py_XDECREF(self->handle_end); 2717 Py_XDECREF(self->handle_end);
2339 Py_XDECREF(self->handle_data); 2718 Py_XDECREF(self->handle_data);
2340 Py_XDECREF(self->handle_start); 2719 Py_XDECREF(self->handle_start);
2341 Py_XDECREF(self->handle_xml); 2720 Py_XDECREF(self->handle_xml);
2342 2721
2343 Py_DECREF(self->target); 2722 Py_DECREF(self->target);
2344 Py_DECREF(self->entity); 2723 Py_DECREF(self->entity);
2345 Py_DECREF(self->names); 2724 Py_DECREF(self->names);
(...skipping 10 matching lines...) Expand all
2356 expat_parse(XMLParserObject* self, char* data, int data_len, int final) 2735 expat_parse(XMLParserObject* self, char* data, int data_len, int final)
2357 { 2736 {
2358 int ok; 2737 int ok;
2359 2738
2360 ok = EXPAT(Parse)(self->parser, data, data_len, final); 2739 ok = EXPAT(Parse)(self->parser, data, data_len, final);
2361 2740
2362 if (PyErr_Occurred()) 2741 if (PyErr_Occurred())
2363 return NULL; 2742 return NULL;
2364 2743
2365 if (!ok) { 2744 if (!ok) {
2366 PyErr_Format( 2745 expat_set_error(
2367 PyExc_SyntaxError, "%s: line %ld, column %ld",
2368 EXPAT(ErrorString)(EXPAT(GetErrorCode)(self->parser)), 2746 EXPAT(ErrorString)(EXPAT(GetErrorCode)(self->parser)),
2369 EXPAT(GetErrorLineNumber)(self->parser), 2747 EXPAT(GetErrorLineNumber)(self->parser),
2370 EXPAT(GetErrorColumnNumber)(self->parser) 2748 EXPAT(GetErrorColumnNumber)(self->parser)
2371 ); 2749 );
2372 return NULL; 2750 return NULL;
2373 } 2751 }
2374 2752
2375 Py_RETURN_NONE; 2753 Py_RETURN_NONE;
2376 } 2754 }
2377 2755
2378 static PyObject* 2756 static PyObject*
2379 xmlparser_close(XMLParserObject* self, PyObject* args) 2757 xmlparser_close(XMLParserObject* self, PyObject* args)
2380 { 2758 {
2381 /* end feeding data to parser */ 2759 /* end feeding data to parser */
2382 2760
2383 PyObject* res; 2761 PyObject* res;
2384 if (!PyArg_ParseTuple(args, ":close")) 2762 if (!PyArg_ParseTuple(args, ":close"))
2385 return NULL; 2763 return NULL;
2386 2764
2387 res = expat_parse(self, "", 0, 1); 2765 res = expat_parse(self, "", 0, 1);
2766 if (!res)
2767 return NULL;
2388 2768
2389 if (res && TreeBuilder_CheckExact(self->target)) { 2769 if (TreeBuilder_CheckExact(self->target)) {
2390 Py_DECREF(res); 2770 Py_DECREF(res);
2391 return treebuilder_done((TreeBuilderObject*) self->target); 2771 return treebuilder_done((TreeBuilderObject*) self->target);
2392 } 2772 } if (self->handle_close) {
2393 2773 Py_DECREF(res);
2394 return res; 2774 return PyObject_CallFunction(self->handle_close, "");
2775 } else
2776 return res;
2395 } 2777 }
2396 2778
2397 static PyObject* 2779 static PyObject*
2398 xmlparser_feed(XMLParserObject* self, PyObject* args) 2780 xmlparser_feed(XMLParserObject* self, PyObject* args)
2399 { 2781 {
2400 /* feed data to parser */ 2782 /* feed data to parser */
2401 2783
2402 char* data; 2784 char* data;
2403 int data_len; 2785 int data_len;
2404 if (!PyArg_ParseTuple(args, "s#:feed", &data, &data_len)) 2786 if (!PyArg_ParseTuple(args, "s#:feed", &data, &data_len))
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 {NULL, NULL} 2950 {NULL, NULL}
2569 }; 2951 };
2570 2952
2571 static PyObject*·· 2953 static PyObject*··
2572 xmlparser_getattr(XMLParserObject* self, char* name) 2954 xmlparser_getattr(XMLParserObject* self, char* name)
2573 { 2955 {
2574 PyObject* res; 2956 PyObject* res;
2575 2957
2576 res = Py_FindMethod(xmlparser_methods, (PyObject*) self, name); 2958 res = Py_FindMethod(xmlparser_methods, (PyObject*) self, name);
2577 if (res) 2959 if (res)
2578 » return res; 2960 return res;
2579 2961
2580 PyErr_Clear(); 2962 PyErr_Clear();
2581 2963
2582 if (strcmp(name, "entity") == 0) 2964 if (strcmp(name, "entity") == 0)
2583 » res = self->entity; 2965 res = self->entity;
2584 else if (strcmp(name, "target") == 0) 2966 else if (strcmp(name, "target") == 0)
2585 » res = self->target; 2967 res = self->target;
2586 else if (strcmp(name, "version") == 0) { 2968 else if (strcmp(name, "version") == 0) {
2587 char buffer[100]; 2969 char buffer[100];
2588 sprintf(buffer, "Expat %d.%d.%d", XML_MAJOR_VERSION, 2970 sprintf(buffer, "Expat %d.%d.%d", XML_MAJOR_VERSION,
2589 XML_MINOR_VERSION, XML_MICRO_VERSION); 2971 XML_MINOR_VERSION, XML_MICRO_VERSION);
2590 return PyString_FromString(buffer); 2972 return PyString_FromString(buffer);
2591 } else { 2973 } else {
2592 PyErr_SetString(PyExc_AttributeError, name); 2974 PyErr_SetString(PyExc_AttributeError, name);
2593 return NULL; 2975 return NULL;
2594 } 2976 }
2595 2977
(...skipping 25 matching lines...) Expand all
2621 #endif 3003 #endif
2622 {NULL, NULL} 3004 {NULL, NULL}
2623 }; 3005 };
2624 3006
2625 DL_EXPORT(void) 3007 DL_EXPORT(void)
2626 init_elementtree(void) 3008 init_elementtree(void)
2627 { 3009 {
2628 PyObject* m; 3010 PyObject* m;
2629 PyObject* g; 3011 PyObject* g;
2630 char* bootstrap; 3012 char* bootstrap;
2631 #if defined(USE_PYEXPAT_CAPI) 3013 static struct cElementTree_CAPI capi;
2632 struct PyExpat_CAPI* capi; 3014 PyObject* capi_object;
2633 #endif
2634 3015
2635 /* Patch object type */ 3016 /* Patch object type */
2636 Py_TYPE(&Element_Type) = Py_TYPE(&TreeBuilder_Type) = &PyType_Type; 3017 Py_TYPE(&Element_Type) = Py_TYPE(&TreeBuilder_Type) = &PyType_Type;
2637 #if defined(USE_EXPAT) 3018 #if defined(USE_EXPAT)
2638 Py_TYPE(&XMLParser_Type) = &PyType_Type; 3019 Py_TYPE(&XMLParser_Type) = &PyType_Type;
2639 #endif 3020 #endif
2640 3021
2641 m = Py_InitModule("_elementtree", _functions); 3022 m = Py_InitModule("_elementtree", _functions);
2642 if (!m) 3023 if (!m)
2643 return; 3024 return;
(...skipping 22 matching lines...) Expand all
2666 "del ElementTree\n" 3047 "del ElementTree\n"
2667 3048
2668 "import _elementtree as cElementTree\n" 3049 "import _elementtree as cElementTree\n"
2669 3050
2670 "try:\n" /* check if copy works as is */ 3051 "try:\n" /* check if copy works as is */
2671 " copy(cElementTree.Element('x'))\n" 3052 " copy(cElementTree.Element('x'))\n"
2672 "except:\n" 3053 "except:\n"
2673 " def copyelement(elem):\n" 3054 " def copyelement(elem):\n"
2674 " return elem\n" 3055 " return elem\n"
2675 3056
2676 "def Comment(text=None):\n" /* public */ 3057 "class CommentProxy:\n"
3058 " def __call__(self, text=None):\n"
2677 " element = cElementTree.Element(ET.Comment)\n" 3059 " element = cElementTree.Element(ET.Comment)\n"
2678 " element.text = text\n" 3060 " element.text = text\n"
2679 " return element\n" 3061 " return element\n"
2680 "cElementTree.Comment = Comment\n" 3062 " def __cmp__(self, other):\n"
3063 " return cmp(ET.Comment, other)\n"
3064 "cElementTree.Comment = CommentProxy()\n"
2681 3065
2682 "class ElementTree(ET.ElementTree):\n" /* public */ 3066 "class ElementTree(ET.ElementTree):\n" /* public */
2683 " def parse(self, source, parser=None):\n" 3067 " def parse(self, source, parser=None):\n"
2684 " if not hasattr(source, 'read'):\n" 3068 " if not hasattr(source, 'read'):\n"
2685 " source = open(source, 'rb')\n" 3069 " source = open(source, 'rb')\n"
2686 " if parser is not None:\n" 3070 " if parser is not None:\n"
2687 " while 1:\n" 3071 " while 1:\n"
2688 " data = source.read(65536)\n" 3072 " data = source.read(65536)\n"
2689 " if not data:\n" 3073 " if not data:\n"
2690 " break\n" 3074 " break\n"
2691 " parser.feed(data)\n" 3075 " parser.feed(data)\n"
2692 " self._root = parser.close()\n" 3076 " self._root = parser.close()\n"
2693 " else:\n"· 3077 " else:\n"·
2694 " parser = cElementTree.XMLParser()\n" 3078 " parser = cElementTree.XMLParser()\n"
2695 " self._root = parser._parse(source)\n" 3079 " self._root = parser._parse(source)\n"
2696 " return self._root\n" 3080 " return self._root\n"
2697 "cElementTree.ElementTree = ElementTree\n" 3081 "cElementTree.ElementTree = ElementTree\n"
2698 3082
2699 "def getiterator(node, tag=None):\n" /* helper */ 3083 "def iter(node, tag=None):\n" /* helper */
2700 " if tag == '*':\n" 3084 " if tag == '*':\n"
2701 " tag = None\n" 3085 " tag = None\n"
2702 #if (PY_VERSION_HEX < 0x02020000) 3086 #if (PY_VERSION_HEX < 0x02020000)
2703 " nodes = []\n" /* 2.1 doesn't have yield */ 3087 " nodes = []\n" /* 2.1 doesn't have yield */
2704 " if tag is None or node.tag == tag:\n" 3088 " if tag is None or node.tag == tag:\n"
2705 " nodes.append(node)\n" 3089 " nodes.append(node)\n"
2706 " for node in node:\n" 3090 " for node in node:\n"
2707 " nodes.extend(getiterator(node, tag))\n" 3091 " nodes.extend(iter(node, tag))\n"
2708 " return nodes\n" 3092 " return nodes\n"
2709 #else 3093 #else
2710 " if tag is None or node.tag == tag:\n" 3094 " if tag is None or node.tag == tag:\n"
2711 " yield node\n" 3095 " yield node\n"
2712 " for node in node:\n" 3096 " for node in node:\n"
2713 " for node in getiterator(node, tag):\n" 3097 " for node in iter(node, tag):\n"
2714 " yield node\n" 3098 " yield node\n"
2715 #endif 3099 #endif
2716 3100
3101 "def itertext(node):\n" /* helper */
3102 " if node.text:\n"
3103 " yield node.text\n"
3104 " for e in node:\n"
3105 " for s in e.itertext():\n"
3106 " yield s\n"
3107 " if e.tail:\n"
3108 " yield e.tail\n"
3109
2717 "def parse(source, parser=None):\n" /* public */ 3110 "def parse(source, parser=None):\n" /* public */
2718 " tree = ElementTree()\n" 3111 " tree = ElementTree()\n"
2719 " tree.parse(source, parser)\n" 3112 " tree.parse(source, parser)\n"
2720 " return tree\n" 3113 " return tree\n"
2721 "cElementTree.parse = parse\n" 3114 "cElementTree.parse = parse\n"
2722 3115
2723 #if (PY_VERSION_HEX < 0x02020000) 3116 #if (PY_VERSION_HEX < 0x02020000)
2724 "if hasattr(ET, 'iterparse'):\n" 3117 "if hasattr(ET, 'iterparse'):\n"
2725 " cElementTree.iterparse = ET.iterparse\n" /* delegate on 2.1 */ 3118 " cElementTree.iterparse = ET.iterparse\n" /* delegate on 2.1 */
2726 #else 3119 #else
2727 "class iterparse(object):\n" 3120 "class iterparse(object):\n"
2728 " root = None\n" 3121 " root = None\n"
2729 " def __init__(self, file, events=None):\n" 3122 " def __init__(self, file, events=None):\n"
2730 " if not hasattr(file, 'read'):\n" 3123 " if not hasattr(file, 'read'):\n"
2731 " file = open(file, 'rb')\n" 3124 " file = open(file, 'rb')\n"
2732 " self._file = file\n" 3125 " self._file = file\n"
2733 " self._events = events\n" 3126 " self._events = []\n"
2734 " def __iter__(self):\n" 3127 " self._index = 0\n"
2735 " events = []\n" 3128 " self.root = self._root = None\n"
2736 " b = cElementTree.TreeBuilder()\n" 3129 " b = cElementTree.TreeBuilder()\n"
2737 " p = cElementTree.XMLParser(b)\n" 3130 " self._parser = cElementTree.XMLParser(b)\n"
2738 " p._setevents(events, self._events)\n" 3131 " self._parser._setevents(self._events, events)\n"
3132 " def next(self):\n"
2739 " while 1:\n" 3133 " while 1:\n"
2740 " data = self._file.read(16384)\n" 3134 " try:\n"
2741 " if not data:\n" 3135 " item = self._events[self._index]\n"
2742 " break\n" 3136 " except IndexError:\n"
2743 " p.feed(data)\n" 3137 " if self._parser is None:\n"
2744 " for event in events:\n" 3138 " self.root = self._root\n"
2745 " yield event\n" 3139 " raise StopIteration\n"
2746 " del events[:]\n" 3140 " # load event buffer\n"
2747 " root = p.close()\n" 3141 " del self._events[:]\n"
2748 " for event in events:\n" 3142 " self._index = 0\n"
2749 " yield event\n" 3143 " data = self._file.read(16384)\n"
2750 " self.root = root\n" 3144 " if data:\n"
3145 " self._parser.feed(data)\n"
3146 " else:\n"
3147 " self._root = self._parser.close()\n"
3148 " self._parser = None\n"
3149 " else:\n"
3150 " self._index = self._index + 1\n"
3151 " return item\n"
3152 " def __iter__(self):\n"
3153 " return self\n"
2751 "cElementTree.iterparse = iterparse\n" 3154 "cElementTree.iterparse = iterparse\n"
2752 #endif 3155 #endif
2753 3156
2754 "def PI(target, text=None):\n" /* public */ 3157 "class PIProxy:\n"
2755 " element = cElementTree.Element(ET.ProcessingInstruction)\n" 3158 " def __call__(self, target, text=None):\n"
3159 " element = cElementTree.Element(ET.PI)\n"
2756 " element.text = target\n" 3160 " element.text = target\n"
2757 " if text:\n" 3161 " if text:\n"
2758 " element.text = element.text + ' ' + text\n" 3162 " element.text = element.text + ' ' + text\n"
2759 " return element\n" 3163 " return element\n"
2760 3164 " def __cmp__(self, other):\n"
2761 " elem = cElementTree.Element(ET.PI)\n" 3165 " return cmp(ET.PI, other)\n"
2762 " elem.text = text\n" 3166 "cElementTree.PI = cElementTree.ProcessingInstruction = PIProxy()\n"
2763 " return elem\n"
2764 "cElementTree.PI = cElementTree.ProcessingInstruction = PI\n"
2765 3167
2766 "def XML(text):\n" /* public */ 3168 "def XML(text):\n" /* public */
2767 " parser = cElementTree.XMLParser()\n" 3169 " parser = cElementTree.XMLParser()\n"
2768 " parser.feed(text)\n" 3170 " parser.feed(text)\n"
2769 " return parser.close()\n" 3171 " return parser.close()\n"
2770 "cElementTree.XML = cElementTree.fromstring = XML\n" 3172 "cElementTree.XML = cElementTree.fromstring = XML\n"
2771 3173
2772 "def XMLID(text):\n" /* public */ 3174 "def XMLID(text):\n" /* public */
2773 " tree = XML(text)\n" 3175 " tree = XML(text)\n"
2774 " ids = {}\n" 3176 " ids = {}\n"
2775 " for elem in tree.getiterator():\n" 3177 " for elem in tree.getiterator():\n"
2776 " id = elem.get('id')\n" 3178 " id = elem.get('id')\n"
2777 " if id:\n" 3179 " if id:\n"
2778 " ids[id] = elem\n" 3180 " ids[id] = elem\n"
2779 " return tree, ids\n" 3181 " return tree, ids\n"
2780 "cElementTree.XMLID = XMLID\n" 3182 "cElementTree.XMLID = XMLID\n"
2781 3183
3184 "try:\n"
3185 " register_namespace = ET.register_namespace\n"
3186 "except AttributeError:\n"
3187 " def register_namespace(prefix, uri):\n"
3188 " ET._namespace_map[uri] = prefix\n"
3189 "cElementTree.register_namespace = register_namespace\n"
3190
2782 "cElementTree.dump = ET.dump\n" 3191 "cElementTree.dump = ET.dump\n"
2783 "cElementTree.ElementPath = ElementPath = ET.ElementPath\n" 3192 "cElementTree.ElementPath = ElementPath = ET.ElementPath\n"
2784 "cElementTree.iselement = ET.iselement\n" 3193 "cElementTree.iselement = ET.iselement\n"
2785 "cElementTree.QName = ET.QName\n" 3194 "cElementTree.QName = ET.QName\n"
2786 "cElementTree.tostring = ET.tostring\n" 3195 "cElementTree.tostring = ET.tostring\n"
3196 "cElementTree.fromstringlist = ET.fromstringlist\n"
3197 "cElementTree.tostringlist = ET.tostringlist\n"
2787 "cElementTree.VERSION = '" VERSION "'\n" 3198 "cElementTree.VERSION = '" VERSION "'\n"
2788 "cElementTree.__version__ = '" VERSION "'\n" 3199 "cElementTree.__version__ = '" VERSION "'\n"
2789 "cElementTree.XMLParserError = SyntaxError\n"
2790 3200
2791 ); 3201 );
2792 3202
2793 PyRun_String(bootstrap, Py_file_input, g, NULL); 3203 if (!PyRun_String(bootstrap, Py_file_input, g, NULL))
3204 return;
2794 3205
2795 elementpath_obj = PyDict_GetItemString(g, "ElementPath"); 3206 elementpath_obj = PyDict_GetItemString(g, "ElementPath");
2796 3207
2797 elementtree_copyelement_obj = PyDict_GetItemString(g, "copyelement"); 3208 elementtree_copyelement_obj = PyDict_GetItemString(g, "copyelement");
2798 if (elementtree_copyelement_obj) { 3209 if (elementtree_copyelement_obj) {
2799 /* reduce hack needed; enable reduce method */ 3210 /* reduce hack needed; enable reduce method */
2800 PyMethodDef* mp; 3211 PyMethodDef* mp;
2801 for (mp = element_methods; mp->ml_name; mp++) 3212 for (mp = element_methods; mp->ml_name; mp++)
2802 if (mp->ml_meth == (PyCFunction) element_reduce) { 3213 if (mp->ml_meth == (PyCFunction) element_reduce) {
2803 mp->ml_name = "__reduce__"; 3214 mp->ml_name = "__reduce__";
2804 break; 3215 break;
2805 } 3216 }
2806 } else 3217 } else
2807 PyErr_Clear(); 3218 PyErr_Clear();
3219
2808 elementtree_deepcopy_obj = PyDict_GetItemString(g, "deepcopy"); 3220 elementtree_deepcopy_obj = PyDict_GetItemString(g, "deepcopy");
2809 elementtree_getiterator_obj = PyDict_GetItemString(g, "getiterator"); 3221 elementtree_iter_obj = PyDict_GetItemString(g, "iter");
3222 elementtree_itertext_obj = PyDict_GetItemString(g, "itertext");
2810 3223
2811 #if defined(USE_PYEXPAT_CAPI) 3224 #if defined(USE_PYEXPAT_CAPI)
2812 /* link against pyexpat, if possible */ 3225 /* link against pyexpat, if possible */
2813 capi = PyCObject_Import("pyexpat", "expat_CAPI"); 3226 expat_capi = PyCObject_Import("pyexpat", "expat_CAPI");
2814 if (capi && 3227 if (expat_capi) {
2815 strcmp(capi->magic, PyExpat_CAPI_MAGIC) == 0 && 3228 /* check that it's usable */
2816 capi->size <= sizeof(*expat_capi) && 3229 if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 ||
2817 capi->MAJOR_VERSION == XML_MAJOR_VERSION && 3230 expat_capi->size < sizeof(struct PyExpat_CAPI) ||
2818 capi->MINOR_VERSION == XML_MINOR_VERSION && 3231 expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION ||
2819 capi->MICRO_VERSION == XML_MICRO_VERSION) 3232 expat_capi->MINOR_VERSION != XML_MINOR_VERSION ||
2820 expat_capi = capi; 3233 expat_capi->MICRO_VERSION != XML_MICRO_VERSION)
2821 else 3234 expat_capi = NULL;
2822 expat_capi = NULL; 3235 }
2823 #endif 3236 #endif
2824 3237
3238 elementtree_parseerror_obj = PyErr_NewException(
3239 "cElementTree.ParseError", PyExc_SyntaxError, NULL
3240 );
3241 Py_INCREF(elementtree_parseerror_obj);
3242 PyModule_AddObject(m, "ParseError", elementtree_parseerror_obj);
3243
3244 capi.size = sizeof(capi);
3245 capi.magic = cElementTree_CAPI_MAGIC;
3246 capi.version = cElementTree_CAPI_VERSION;
3247 capi.type = (PyObject*) &Element_Type;
3248 capi.assert = element_capi_assert;
3249 capi.snapshot = element_capi_snapshot;
3250 capi.getitem = element_capi_getitem;
3251
3252 /* export as cobject */
3253 capi_object = PyCObject_FromVoidPtr(&capi, NULL);
3254 if (capi_object)
3255 PyModule_AddObject(m, "CAPI", capi_object);
2825 } 3256 }
OLDNEW
« no previous file with comments | « Lib/xml/etree/__init__.py ('k') | Modules/celementtree.h » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b