[Python-checkins] GH-92123: Move _elementtree heap types to module state (#101187)

erlend-aasland webhook-mailer at python.org
Sat Jan 21 06:01:21 EST 2023


https://github.com/python/cpython/commit/13566a37c2f27b7f3a5ef1ecf4288230171b7daf
commit: 13566a37c2f27b7f3a5ef1ecf4288230171b7daf
branch: main
author: Erlend E. Aasland <erlend.aasland at protonmail.com>
committer: erlend-aasland <erlend.aasland at protonmail.com>
date: 2023-01-21T12:01:15+01:00
summary:

GH-92123: Move _elementtree heap types to module state (#101187)

files:
M Modules/_elementtree.c
M Modules/clinic/_elementtree.c.h
M Tools/c-analyzer/cpython/globals-to-fix.tsv

diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 93a9d609d7a0..3be098a7dbf6 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -69,13 +69,6 @@ static void _clear_joined_ptr(PyObject **p)
     }
 }
 
-/* Types defined by this extension */
-static PyTypeObject *Element_Type;
-static PyTypeObject *ElementIter_Type;
-static PyTypeObject *TreeBuilder_Type;
-static PyTypeObject *XMLParser_Type;
-
-
 /* Per-module state; PEP 3121 */
 typedef struct {
     PyObject *parseerror_obj;
@@ -92,6 +85,11 @@ typedef struct {
     PyObject *str_findall;
     PyObject *str_iterfind;
     PyObject *str_doctype;
+    /* Types defined by this extension */
+    PyTypeObject *Element_Type;
+    PyTypeObject *ElementIter_Type;
+    PyTypeObject *TreeBuilder_Type;
+    PyTypeObject *XMLParser_Type;
 } elementtreestate;
 
 static struct PyModuleDef elementtreemodule;
@@ -132,6 +130,12 @@ elementtree_clear(PyObject *m)
     Py_CLEAR(st->str_tail);
     Py_CLEAR(st->str_text);
     Py_CLEAR(st->str_doctype);
+
+    // Heap types
+    Py_CLEAR(st->Element_Type);
+    Py_CLEAR(st->ElementIter_Type);
+    Py_CLEAR(st->TreeBuilder_Type);
+    Py_CLEAR(st->XMLParser_Type);
     return 0;
 }
 
@@ -144,6 +148,12 @@ elementtree_traverse(PyObject *m, visitproc visit, void *arg)
     Py_VISIT(st->elementpath_obj);
     Py_VISIT(st->comment_factory);
     Py_VISIT(st->pi_factory);
+
+    // Heap types
+    Py_VISIT(st->Element_Type);
+    Py_VISIT(st->ElementIter_Type);
+    Py_VISIT(st->TreeBuilder_Type);
+    Py_VISIT(st->XMLParser_Type);
     return 0;
 }
 
@@ -223,8 +233,8 @@ typedef struct {
 } ElementObject;
 
 
-#define Element_CheckExact(op) Py_IS_TYPE(op, Element_Type)
-#define Element_Check(op) PyObject_TypeCheck(op, Element_Type)
+#define Element_CheckExact(st, op) Py_IS_TYPE(op, (st)->Element_Type)
+#define Element_Check(st, op) PyObject_TypeCheck(op, (st)->Element_Type)
 
 
 /* -------------------------------------------------------------------- */
@@ -291,7 +301,8 @@ create_new_element(PyObject* tag, PyObject* attrib)
 {
     ElementObject* self;
 
-    self = PyObject_GC_New(ElementObject, Element_Type);
+    elementtreestate *st = ET_STATE_GLOBAL;
+    self = PyObject_GC_New(ElementObject, st->Element_Type);
     if (self == NULL)
         return NULL;
     self->extra = NULL;
@@ -373,11 +384,11 @@ get_attrib_from_keywords(PyObject *kwds)
 
 /*[clinic input]
 module _elementtree
-class _elementtree.Element "ElementObject *" "Element_Type"
-class _elementtree.TreeBuilder "TreeBuilderObject *" "TreeBuilder_Type"
-class _elementtree.XMLParser "XMLParserObject *" "XMLParser_Type"
+class _elementtree.Element "ElementObject *" "clinic_state()->Element_Type"
+class _elementtree.TreeBuilder "TreeBuilderObject *" "clinic_state()->TreeBuilder_Type"
+class _elementtree.XMLParser "XMLParserObject *" "clinic_state()->XMLParser_Type"
 [clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1ecdb32b55d9d5de]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6c83ea832d2b0ef1]*/
 
 static int
 element_init(PyObject *self, PyObject *args, PyObject *kwds)
@@ -496,8 +507,8 @@ LOCAL(int)
 element_add_subelement(ElementObject* self, PyObject* element)
 {
     /* add a child element to a parent */
-
-    if (!Element_Check(element)) {
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (!Element_Check(st, element)) {
         raise_type_error(element);
         return -1;
     }
@@ -575,11 +586,12 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds)
 {
     PyObject* elem;
 
+    elementtreestate *st = ET_STATE_GLOBAL;
     ElementObject* parent;
     PyObject* tag;
     PyObject* attrib = NULL;
     if (!PyArg_ParseTuple(args, "O!O|O!:SubElement",
-                          Element_Type, &parent, &tag,
+                          st->Element_Type, &parent, &tag,
                           &PyDict_Type, &attrib)) {
         return NULL;
     }
@@ -673,14 +685,14 @@ element_dealloc(ElementObject* self)
 /*[clinic input]
 _elementtree.Element.append
 
-    subelement: object(subclass_of='Element_Type')
+    subelement: object(subclass_of='clinic_state()->Element_Type')
     /
 
 [clinic start generated code]*/
 
 static PyObject *
 _elementtree_Element_append_impl(ElementObject *self, PyObject *subelement)
-/*[clinic end generated code: output=54a884b7cf2295f4 input=59866b732e6e2891]*/
+/*[clinic end generated code: output=54a884b7cf2295f4 input=439f2bd777288fb6]*/
 {
     if (element_add_subelement(self, subelement) < 0)
         return NULL;
@@ -806,9 +818,10 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo)
         if (element_resize(element, self->extra->length) < 0)
             goto error;
 
+        elementtreestate *st = ET_STATE_GLOBAL;
         for (i = 0; i < self->extra->length; i++) {
             PyObject* child = deepcopy(self->extra->children[i], memo);
-            if (!child || !Element_Check(child)) {
+            if (!child || !Element_Check(st, child)) {
                 if (child) {
                     raise_type_error(child);
                     Py_DECREF(child);
@@ -846,7 +859,7 @@ LOCAL(PyObject *)
 deepcopy(PyObject *object, PyObject *memo)
 {
     /* do a deep copy of the given object */
-    elementtreestate *st;
+    elementtreestate *st = ET_STATE_GLOBAL;
     PyObject *stack[2];
 
     /* Fast paths */
@@ -869,14 +882,13 @@ deepcopy(PyObject *object, PyObject *memo)
                 return PyDict_Copy(object);
             /* Fall through to general case */
         }
-        else if (Element_CheckExact(object)) {
+        else if (Element_CheckExact(st, object)) {
             return _elementtree_Element___deepcopy___impl(
                 (ElementObject *)object, memo);
         }
     }
 
     /* General case */
-    st = ET_STATE_GLOBAL;
     if (!st->deepcopy_obj) {
         PyErr_SetString(PyExc_RuntimeError,
                         "deepcopy helper not found");
@@ -1020,9 +1032,10 @@ element_setstate_from_attributes(ElementObject *self,
         }
 
         /* Copy children */
+        elementtreestate *st = ET_STATE_GLOBAL;
         for (i = 0; i < nchildren; i++) {
             PyObject *child = PyList_GET_ITEM(children, i);
-            if (!Element_Check(child)) {
+            if (!Element_Check(st, child)) {
                 raise_type_error(child);
                 self->extra->length = i;
                 dealloc_extra(oldextra);
@@ -1220,7 +1233,7 @@ _elementtree_Element_find_impl(ElementObject *self, PyObject *path,
     for (i = 0; i < self->extra->length; i++) {
         PyObject* item = self->extra->children[i];
         int rc;
-        assert(Element_Check(item));
+        assert(Element_Check(st, item));
         Py_INCREF(item);
         rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
         if (rc > 0)
@@ -1264,7 +1277,7 @@ _elementtree_Element_findtext_impl(ElementObject *self, PyObject *path,
     for (i = 0; i < self->extra->length; i++) {
         PyObject *item = self->extra->children[i];
         int rc;
-        assert(Element_Check(item));
+        assert(Element_Check(st, item));
         Py_INCREF(item);
         rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
         if (rc > 0) {
@@ -1318,7 +1331,7 @@ _elementtree_Element_findall_impl(ElementObject *self, PyObject *path,
     for (i = 0; i < self->extra->length; i++) {
         PyObject* item = self->extra->children[i];
         int rc;
-        assert(Element_Check(item));
+        assert(Element_Check(st, item));
         Py_INCREF(item);
         rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
         if (rc != 0 && (rc < 0 || PyList_Append(out, item) < 0)) {
@@ -1440,7 +1453,7 @@ element_getitem(PyObject* self_, Py_ssize_t index)
 _elementtree.Element.insert
 
     index: Py_ssize_t
-    subelement: object(subclass_of='Element_Type')
+    subelement: object(subclass_of='clinic_state()->Element_Type')
     /
 
 [clinic start generated code]*/
@@ -1448,7 +1461,7 @@ _elementtree.Element.insert
 static PyObject *
 _elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index,
                                  PyObject *subelement)
-/*[clinic end generated code: output=990adfef4d424c0b input=4382c42ab2659f9b]*/
+/*[clinic end generated code: output=990adfef4d424c0b input=9530f4905aa401ca]*/
 {
     Py_ssize_t i;
 
@@ -1547,14 +1560,14 @@ _elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag,
 /*[clinic input]
 _elementtree.Element.remove
 
-    subelement: object(subclass_of='Element_Type')
+    subelement: object(subclass_of='clinic_state()->Element_Type')
     /
 
 [clinic start generated code]*/
 
 static PyObject *
 _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement)
-/*[clinic end generated code: output=38fe6c07d6d87d1f input=cbdf9f2ab34d93b0]*/
+/*[clinic end generated code: output=38fe6c07d6d87d1f input=6133e1d05597d5ee]*/
 {
     Py_ssize_t i;
     int rc;
@@ -1668,7 +1681,8 @@ element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item)
     old = self->extra->children[index];
 
     if (item) {
-        if (!Element_Check(item)) {
+        elementtreestate *st = ET_STATE_GLOBAL;
+        if (!Element_Check(st, item)) {
             raise_type_error(item);
             return -1;
         }
@@ -1865,9 +1879,10 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value)
             }
         }
 
+        elementtreestate *st = ET_STATE_GLOBAL;
         for (i = 0; i < newlen; i++) {
             PyObject *element = PySequence_Fast_GET_ITEM(seq, i);
-            if (!Element_Check(element)) {
+            if (!Element_Check(st, element)) {
                 raise_type_error(element);
                 Py_DECREF(seq);
                 return -1;
@@ -2140,7 +2155,10 @@ elementiter_next(ElementIterObject *it)
                 continue;
             }
 
-            assert(Element_Check(extra->children[child_index]));
+#ifndef NDEBUG
+            elementtreestate *st = ET_STATE_GLOBAL;
+            assert(Element_Check(st, extra->children[child_index]));
+#endif
             elem = (ElementObject *)Py_NewRef(extra->children[child_index]);
             item->child_index++;
         }
@@ -2215,7 +2233,8 @@ create_elementiter(ElementObject *self, PyObject *tag, int gettext)
 {
     ElementIterObject *it;
 
-    it = PyObject_GC_New(ElementIterObject, ElementIter_Type);
+    elementtreestate *st = ET_STATE_GLOBAL;
+    it = PyObject_GC_New(ElementIterObject, st->ElementIter_Type);
     if (!it)
         return NULL;
 
@@ -2272,7 +2291,7 @@ typedef struct {
     char insert_pis;
 } TreeBuilderObject;
 
-#define TreeBuilder_CheckExact(op) Py_IS_TYPE((op), TreeBuilder_Type)
+#define TreeBuilder_CheckExact(st, op) Py_IS_TYPE((op), (st)->TreeBuilder_Type)
 
 /* -------------------------------------------------------------------- */
 /* constructor and destructor */
@@ -2472,7 +2491,8 @@ treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data,
                                         PyObject **dest, PyObject *name)
 {
     /* Fast paths for the "almost always" cases. */
-    if (Element_CheckExact(element)) {
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (Element_CheckExact(st, element)) {
         PyObject *dest_obj = JOIN_OBJ(*dest);
         if (dest_obj == Py_None) {
             *dest = JOIN_SET(*data, PyList_CheckExact(*data));
@@ -2546,7 +2566,7 @@ static int
 treebuilder_add_subelement(PyObject *element, PyObject *child)
 {
     elementtreestate *st = ET_STATE_GLOBAL;
-    if (Element_CheckExact(element)) {
+    if (Element_CheckExact(st, element)) {
         ElementObject *elem = (ElementObject *) element;
         return element_add_subelement(elem, child);
     }
@@ -3121,7 +3141,8 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in,
     value = PyDict_GetItemWithError(self->entity, key);
 
     if (value) {
-        if (TreeBuilder_CheckExact(self->target))
+        elementtreestate *st = ET_STATE_GLOBAL;
+        if (TreeBuilder_CheckExact(st, self->target))
             res = treebuilder_handle_data(
                 (TreeBuilderObject*) self->target, value
                 );
@@ -3193,7 +3214,8 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
         attrib = NULL;
     }
 
-    if (TreeBuilder_CheckExact(self->target)) {
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (TreeBuilder_CheckExact(st, self->target)) {
         /* shortcut */
         res = treebuilder_handle_start((TreeBuilderObject*) self->target,
                                        tag, attrib);
@@ -3231,7 +3253,8 @@ expat_data_handler(XMLParserObject* self, const XML_Char* data_in,
     if (!data)
         return; /* parser will look for errors */
 
-    if (TreeBuilder_CheckExact(self->target))
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (TreeBuilder_CheckExact(st, self->target))
         /* shortcut */
         res = treebuilder_handle_data((TreeBuilderObject*) self->target, data);
     else if (self->handle_data)
@@ -3253,7 +3276,8 @@ expat_end_handler(XMLParserObject* self, const XML_Char* tag_in)
     if (PyErr_Occurred())
         return;
 
-    if (TreeBuilder_CheckExact(self->target))
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (TreeBuilder_CheckExact(st, self->target))
         /* shortcut */
         /* the standard tree builder doesn't look at the end tag */
         res = treebuilder_handle_end(
@@ -3287,7 +3311,8 @@ expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix_in,
     if (!prefix_in)
         prefix_in = "";
 
-    if (TreeBuilder_CheckExact(self->target)) {
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (TreeBuilder_CheckExact(st, self->target)) {
         /* shortcut - TreeBuilder does not actually implement .start_ns() */
         TreeBuilderObject *target = (TreeBuilderObject*) self->target;
 
@@ -3337,7 +3362,8 @@ expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in)
     if (!prefix_in)
         prefix_in = "";
 
-    if (TreeBuilder_CheckExact(self->target)) {
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (TreeBuilder_CheckExact(st, self->target)) {
         /* shortcut - TreeBuilder does not actually implement .end_ns() */
         TreeBuilderObject *target = (TreeBuilderObject*) self->target;
 
@@ -3365,7 +3391,8 @@ expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in)
     if (PyErr_Occurred())
         return;
 
-    if (TreeBuilder_CheckExact(self->target)) {
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (TreeBuilder_CheckExact(st, self->target)) {
         /* shortcut */
         TreeBuilderObject *target = (TreeBuilderObject*) self->target;
 
@@ -3458,7 +3485,8 @@ expat_pi_handler(XMLParserObject* self, const XML_Char* target_in,
     if (PyErr_Occurred())
         return;
 
-    if (TreeBuilder_CheckExact(self->target)) {
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (TreeBuilder_CheckExact(st, self->target)) {
         /* shortcut */
         TreeBuilderObject *target = (TreeBuilderObject*) self->target;
 
@@ -3566,7 +3594,8 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target,
     if (target != Py_None) {
         Py_INCREF(target);
     } else {
-        target = treebuilder_new(TreeBuilder_Type, NULL, NULL);
+        elementtreestate *st = ET_STATE_GLOBAL;
+        target = treebuilder_new(st->TreeBuilder_Type, NULL, NULL);
         if (!target) {
             Py_CLEAR(self->entity);
             Py_CLEAR(self->names);
@@ -3767,7 +3796,8 @@ _elementtree_XMLParser_close_impl(XMLParserObject *self)
     if (!res)
         return NULL;
 
-    if (TreeBuilder_CheckExact(self->target)) {
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (TreeBuilder_CheckExact(st, self->target)) {
         Py_DECREF(res);
         return treebuilder_done((TreeBuilderObject*) self->target);
     }
@@ -3906,7 +3936,8 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file)
 
     res = expat_parse(self, "", 0, 1);
 
-    if (res && TreeBuilder_CheckExact(self->target)) {
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (res && TreeBuilder_CheckExact(st, self->target)) {
         Py_DECREF(res);
         return treebuilder_done((TreeBuilderObject*) self->target);
     }
@@ -3937,7 +3968,8 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self,
     if (!_check_xmlparser(self)) {
         return NULL;
     }
-    if (!TreeBuilder_CheckExact(self->target)) {
+    elementtreestate *st = ET_STATE_GLOBAL;
+    if (!TreeBuilder_CheckExact(st, self->target)) {
         PyErr_SetString(
             PyExc_TypeError,
             "event handling only supported for ElementTree.TreeBuilder "
@@ -4046,7 +4078,9 @@ static PyGetSetDef xmlparser_getsetlist[] = {
     {NULL},
 };
 
+#define clinic_state() (ET_STATE_GLOBAL)
 #include "clinic/_elementtree.c.h"
+#undef clinic_state
 
 static PyMethodDef element_methods[] = {
 
@@ -4243,10 +4277,10 @@ PyInit__elementtree(void)
     st = get_elementtree_state(m);
 
     /* Initialize object types */
-    CREATE_TYPE(m, ElementIter_Type, &elementiter_spec);
-    CREATE_TYPE(m, TreeBuilder_Type, &treebuilder_spec);
-    CREATE_TYPE(m, Element_Type, &element_spec);
-    CREATE_TYPE(m, XMLParser_Type, &xmlparser_spec);
+    CREATE_TYPE(m, st->ElementIter_Type, &elementiter_spec);
+    CREATE_TYPE(m, st->TreeBuilder_Type, &treebuilder_spec);
+    CREATE_TYPE(m, st->Element_Type, &element_spec);
+    CREATE_TYPE(m, st->XMLParser_Type, &xmlparser_spec);
 
     st->deepcopy_obj = _PyImport_GetModuleAttrString("copy", "deepcopy");
     if (st->deepcopy_obj == NULL) {
@@ -4314,9 +4348,9 @@ PyInit__elementtree(void)
     }
 
     PyTypeObject *types[] = {
-        Element_Type,
-        TreeBuilder_Type,
-        XMLParser_Type
+        st->Element_Type,
+        st->TreeBuilder_Type,
+        st->XMLParser_Type
     };
 
     for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) {
diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h
index b816e1bd8559..4bf342c8b60d 100644
--- a/Modules/clinic/_elementtree.c.h
+++ b/Modules/clinic/_elementtree.c.h
@@ -25,8 +25,8 @@ _elementtree_Element_append(ElementObject *self, PyObject *arg)
     PyObject *return_value = NULL;
     PyObject *subelement;
 
-    if (!PyObject_TypeCheck(arg, Element_Type)) {
-        _PyArg_BadArgument("append", "argument", (Element_Type)->tp_name, arg);
+    if (!PyObject_TypeCheck(arg, clinic_state()->Element_Type)) {
+        _PyArg_BadArgument("append", "argument", (clinic_state()->Element_Type)->tp_name, arg);
         goto exit;
     }
     subelement = arg;
@@ -586,8 +586,8 @@ _elementtree_Element_insert(ElementObject *self, PyObject *const *args, Py_ssize
         }
         index = ival;
     }
-    if (!PyObject_TypeCheck(args[1], Element_Type)) {
-        _PyArg_BadArgument("insert", "argument 2", (Element_Type)->tp_name, args[1]);
+    if (!PyObject_TypeCheck(args[1], clinic_state()->Element_Type)) {
+        _PyArg_BadArgument("insert", "argument 2", (clinic_state()->Element_Type)->tp_name, args[1]);
         goto exit;
     }
     subelement = args[1];
@@ -682,8 +682,8 @@ _elementtree_Element_remove(ElementObject *self, PyObject *arg)
     PyObject *return_value = NULL;
     PyObject *subelement;
 
-    if (!PyObject_TypeCheck(arg, Element_Type)) {
-        _PyArg_BadArgument("remove", "argument", (Element_Type)->tp_name, arg);
+    if (!PyObject_TypeCheck(arg, clinic_state()->Element_Type)) {
+        _PyArg_BadArgument("remove", "argument", (clinic_state()->Element_Type)->tp_name, arg);
         goto exit;
     }
     subelement = arg;
@@ -1105,4 +1105,4 @@ _elementtree_XMLParser__setevents(XMLParserObject *self, PyObject *const *args,
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=db3d6654de9f8013 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=d380adb43d8f4a62 input=a9049054013a1b77]*/
diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv
index cd08782edce4..761a2ab43e6c 100644
--- a/Tools/c-analyzer/cpython/globals-to-fix.tsv
+++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv
@@ -425,10 +425,6 @@ Modules/_decimal/_decimal.c	-	PyDecContextManager_Type	-
 Modules/_decimal/_decimal.c	-	PyDecContext_Type	-
 Modules/_decimal/_decimal.c	-	PyDecSignalDictMixin_Type	-
 Modules/_decimal/_decimal.c	-	PyDec_Type	-
-Modules/_elementtree.c	-	ElementIter_Type	-
-Modules/_elementtree.c	-	Element_Type	-
-Modules/_elementtree.c	-	TreeBuilder_Type	-
-Modules/_elementtree.c	-	XMLParser_Type	-
 Modules/_pickle.c	-	Pdata_Type	-
 Modules/_pickle.c	-	PicklerMemoProxyType	-
 Modules/_pickle.c	-	Pickler_Type	-



More information about the Python-checkins mailing list