diff -r 3ca4bfca3039 Modules/_elementtree.c --- a/Modules/_elementtree.c Fri Dec 14 17:29:31 2012 +0100 +++ b/Modules/_elementtree.c Fri Dec 14 17:31:38 2012 +0100 @@ -101,9 +101,54 @@ #define JOIN_OBJ(p) ((PyObject*) ((Py_uintptr_t) (p) & ~(Py_uintptr_t)1)) /* glue functions (see the init function for details) */ -static PyObject* elementtree_parseerror_obj; -static PyObject* elementtree_deepcopy_obj; -static PyObject* elementpath_obj; + +typedef struct { + PyObject* elementtree_parseerror_obj; + PyObject* elementtree_deepcopy_obj; + PyObject* elementpath_obj; + PyObject* TreeBuilder_Type; + PyObject* Element_Type; + PyObject* XMLParser_Type; + PyObject* ElementIter_Type; +} _elementtreestate; + +#define _elementtreestate(o) ((_elementtreestate *)PyModule_GetState(o)) + +static int +_elementtree_clear(PyObject *m) +{ + Py_CLEAR(_elementtreestate(m)->elementtree_parseerror_obj); + Py_CLEAR(_elementtreestate(m)->elementtree_deepcopy_obj); + Py_CLEAR(_elementtreestate(m)->elementpath_obj); + Py_CLEAR(_elementtreestate(m)->TreeBuilder_Type); + Py_CLEAR(_elementtreestate(m)->Element_Type); + Py_CLEAR(_elementtreestate(m)->XMLParser_Type); + Py_CLEAR(_elementtreestate(m)->ElementIter_Type); + return 0; +} + +static int +_elementtree_traverse(PyObject *m, visitproc visit, void *arg) +{ + Py_VISIT(_elementtreestate(m)->elementtree_parseerror_obj); + Py_VISIT(_elementtreestate(m)->elementtree_deepcopy_obj); + Py_VISIT(_elementtreestate(m)->elementpath_obj); + Py_VISIT(_elementtreestate(m)->TreeBuilder_Type); + Py_VISIT(_elementtreestate(m)->Element_Type); + Py_VISIT(_elementtreestate(m)->XMLParser_Type); + Py_VISIT(_elementtreestate(m)->ElementIter_Type); + return 0; +} + +static void +_elementtree_free(void *m) +{ + _elementtree_clear((PyObject *)m); +} + +static struct PyModuleDef _elementtreemodule; + +# define _elementtreestate_global ((_elementtreestate *)PyModule_GetState(PyState_FindModule(&_elementtreemodule))) /* helpers */ @@ -115,7 +160,7 @@ PyObject* args; PyObject* result; - if (!elementtree_deepcopy_obj) { + if (!_elementtreestate_global->elementtree_deepcopy_obj) { PyErr_SetString( PyExc_RuntimeError, "deepcopy helper not found" @@ -126,7 +171,7 @@ args = PyTuple_Pack(2, object, memo); if (!args) return NULL; - result = PyObject_CallObject(elementtree_deepcopy_obj, args); + result = PyObject_CallObject(_elementtreestate_global->elementtree_deepcopy_obj, args); Py_DECREF(args); return result; } @@ -200,9 +245,8 @@ } ElementObject; -static PyTypeObject Element_Type; - -#define Element_CheckExact(op) (Py_TYPE(op) == &Element_Type) + +#define Element_CheckExact(op) (Py_TYPE(op) == (PyTypeObject *)_elementtreestate_global->Element_Type) /* -------------------------------------------------------------------- */ /* Element constructors and destructor */ @@ -260,14 +304,18 @@ { ElementObject* self; - self = PyObject_GC_New(ElementObject, &Element_Type); + self = PyObject_GC_New(ElementObject, (PyTypeObject *)_elementtreestate_global->Element_Type); + if (self == NULL) return NULL; self->extra = NULL; + Py_INCREF(_elementtreestate_global->Element_Type); + if (attrib != Py_None && !is_empty_dict(attrib)) { if (create_extra(self, attrib) < 0) { PyObject_Del(self); + Py_DECREF(_elementtreestate_global->Element_Type); return NULL; } } @@ -293,6 +341,7 @@ { ElementObject *e = (ElementObject *)type->tp_alloc(type, 0); if (e != NULL) { + Py_INCREF(type); Py_INCREF(Py_None); e->tag = Py_None; @@ -539,8 +588,8 @@ PyObject* tag; PyObject* attrib = NULL; if (!PyArg_ParseTuple(args, "O!O|O!:SubElement", - &Element_Type, &parent, &tag, - &PyDict_Type, &attrib)) + (PyTypeObject *)_elementtreestate_global->Element_Type, + &parent, &tag, &PyDict_Type, &attrib)) return NULL; if (attrib) { @@ -624,6 +673,7 @@ static void element_dealloc(ElementObject* self) { + PyTypeObject *type = Py_TYPE(self); PyObject_GC_UnTrack(self); if (self->weakreflist != NULL) @@ -634,7 +684,10 @@ element_gc_clear(self); RELEASE(sizeof(ElementObject), "destroy element"); - Py_TYPE(self)->tp_free((PyObject *)self); + type->tp_free((PyObject *)self); + if((void *)type->tp_dealloc == (void *)element_dealloc) { + Py_DECREF(type); + } } /* -------------------------------------------------------------------- */ @@ -644,7 +697,8 @@ element_append(ElementObject* self, PyObject* args) { PyObject* element; - if (!PyArg_ParseTuple(args, "O!:append", &Element_Type, &element)) + if (!PyArg_ParseTuple(args, "O!:append", + (PyTypeObject *)_elementtreestate_global->Element_Type, &element)) return NULL; if (element_add_subelement(self, element) < 0) @@ -878,7 +932,7 @@ seqlen = PySequence_Size(seq); for (i = 0; i < seqlen; i++) { PyObject* element = PySequence_Fast_GET_ITEM(seq, i); - if (!PyObject_IsInstance(element, (PyObject *)&Element_Type)) { + if (!PyObject_IsInstance(element, _elementtreestate_global->Element_Type)) { Py_DECREF(seq); PyErr_Format( PyExc_TypeError, @@ -913,8 +967,8 @@ if (checkpath(tag) || namespaces != Py_None) { _Py_IDENTIFIER(find); return _PyObject_CallMethodId( - elementpath_obj, &PyId_find, "OOO", self, tag, namespaces - ); + _elementtreestate_global->elementpath_obj, &PyId_find, "OOO", + self, tag, namespaces); } if (!self->extra) @@ -948,8 +1002,8 @@ if (checkpath(tag) || namespaces != Py_None) return _PyObject_CallMethodId( - elementpath_obj, &PyId_findtext, "OOOO", self, tag, default_value, namespaces - ); + _elementtreestate_global->elementpath_obj, &PyId_findtext, "OOOO", + self, tag, default_value, namespaces); if (!self->extra) { Py_INCREF(default_value); @@ -988,8 +1042,8 @@ if (checkpath(tag) || namespaces != Py_None) { _Py_IDENTIFIER(findall); return _PyObject_CallMethodId( - elementpath_obj, &PyId_findall, "OOO", self, tag, namespaces - ); + _elementtreestate_global->elementpath_obj, &PyId_findall, "OOO", + self, tag, namespaces); } out = PyList_New(0); @@ -1026,8 +1080,8 @@ return NULL; return _PyObject_CallMethodId( - elementpath_obj, &PyId_iterfind, "OOO", self, tag, namespaces - ); + _elementtreestate_global->elementpath_obj, &PyId_iterfind, "OOO", + self, tag, namespaces); } static PyObject* @@ -1130,7 +1184,7 @@ int index; PyObject* element; if (!PyArg_ParseTuple(args, "iO!:insert", &index, - &Element_Type, &element)) + (PyTypeObject *)_elementtreestate_global->Element_Type, &element)) return NULL; if (!self->extra) @@ -1218,7 +1272,8 @@ int i; PyObject* element; - if (!PyArg_ParseTuple(args, "O!:remove", &Element_Type, &element)) + if (!PyArg_ParseTuple(args, "O!:remove", + (PyTypeObject *)_elementtreestate_global->Element_Type, &element)) return NULL; if (!self->extra) { @@ -1668,63 +1723,34 @@ return NULL; } -static PySequenceMethods element_as_sequence = { - (lenfunc) element_length, - 0, /* sq_concat */ - 0, /* sq_repeat */ - element_getitem, +static PyType_Slot Element_Type_slots[] = { + {Py_tp_dealloc, (destructor)element_dealloc}, + {Py_tp_repr, (reprfunc)element_repr}, + {Py_sq_length, element_length}, + {Py_sq_item, element_getitem}, + {Py_sq_ass_item, element_setitem}, + {Py_mp_length, element_length}, + {Py_mp_subscript, element_subscr}, + {Py_mp_ass_subscript, element_ass_subscr}, + {Py_tp_getattro, (getattrofunc)element_getattro}, + {Py_tp_setattro, (setattrofunc)element_setattro}, + {Py_tp_traverse, (traverseproc)element_gc_traverse}, + {Py_tp_clear, (inquiry)element_gc_clear}, + {Py_tp_methods, element_methods}, + {Py_tp_init, (initproc)element_init}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, element_new}, + {0, 0} +}; + +static PyType_Spec Element_Type_spec = { + "Element", + sizeof(ElementObject), 0, - element_setitem, - 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + Element_Type_slots, }; -static PyMappingMethods element_as_mapping = { - (lenfunc) element_length, - (binaryfunc) element_subscr, - (objobjargproc) element_ass_subscr, -}; - -static PyTypeObject Element_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "Element", sizeof(ElementObject), 0, - /* methods */ - (destructor)element_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)element_repr, /* tp_repr */ - 0, /* tp_as_number */ - &element_as_sequence, /* tp_as_sequence */ - &element_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - (getattrofunc)element_getattro, /* tp_getattro */ - (setattrofunc)element_setattro, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)element_gc_traverse, /* tp_traverse */ - (inquiry)element_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(ElementObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - element_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)element_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - element_new, /* tp_new */ - 0, /* tp_free */ -}; /******************************* Element iterator ****************************/ @@ -1755,6 +1781,7 @@ static void elementiter_dealloc(ElementIterObject *it) { + PyTypeObject *type = Py_TYPE(it); ParentLocator *p = it->parent_stack; while (p) { ParentLocator *temp = p; @@ -1768,6 +1795,9 @@ PyObject_GC_UnTrack(it); PyObject_GC_Del(it); + if((void *)type->tp_dealloc == (void *)elementiter_dealloc) { + Py_DECREF(type); + } } static int @@ -1803,7 +1833,7 @@ elementiter_next(ElementIterObject *it) { /* Sub-element iterator. - * + * * A short note on gettext: this function serves both the iter() and * itertext() methods to avoid code duplication. However, there are a few * small differences in the way these iterations work. Namely: @@ -1885,7 +1915,7 @@ continue; } else { - PyObject *tail = it->gettext ? JOIN_OBJ(cur_parent->tail) : Py_None; + PyObject *tail = it->gettext ? JOIN_OBJ(cur_parent->tail) : Py_None; ParentLocator *next = it->parent_stack->next; Py_XDECREF(it->parent_stack->parent); PyObject_Free(it->parent_stack); @@ -1906,48 +1936,23 @@ } -static PyTypeObject ElementIter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_elementtree._element_iterator", /* tp_name */ - sizeof(ElementIterObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)elementiter_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)elementiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)elementiter_next, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ +static PyType_Slot ElementIter_Type_slots[] = { + {Py_tp_dealloc, (destructor)elementiter_dealloc}, + {Py_tp_traverse, (traverseproc)elementiter_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, elementiter_next}, + {0, 0} }; +static PyType_Spec ElementIter_Type_spec = { + "_elementtree._element_iterator", + sizeof(ElementIterObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + ElementIter_Type_slots, +}; + + static PyObject * create_elementiter(ElementObject *self, PyObject *tag, int gettext) @@ -1955,7 +1960,7 @@ ElementIterObject *it; PyObject *star = NULL; - it = PyObject_GC_New(ElementIterObject, &ElementIter_Type); + it = PyObject_GC_New(ElementIterObject, (PyTypeObject *)_elementtreestate_global->ElementIter_Type); if (!it) return NULL; if (!(it->parent_stack = PyObject_Malloc(sizeof(ParentLocator)))) { @@ -1963,6 +1968,7 @@ return NULL; } + Py_INCREF(_elementtreestate_global->ElementIter_Type); it->parent_stack->parent = NULL; it->parent_stack->child_index = 0; it->parent_stack->next = NULL; @@ -2015,9 +2021,8 @@ PyObject *end_ns_event_obj; } TreeBuilderObject; -static PyTypeObject TreeBuilder_Type; - -#define TreeBuilder_CheckExact(op) (Py_TYPE(op) == &TreeBuilder_Type) + +#define TreeBuilder_CheckExact(op) (Py_TYPE(op) == (PyTypeObject *)_elementtreestate_global->TreeBuilder_Type) /* -------------------------------------------------------------------- */ /* constructor and destructor */ @@ -2027,6 +2032,7 @@ { TreeBuilderObject *t = (TreeBuilderObject *)type->tp_alloc(type, 0); if (t != NULL) { + Py_INCREF(type); t->root = NULL; Py_INCREF(Py_None); @@ -2107,9 +2113,13 @@ static void treebuilder_dealloc(TreeBuilderObject *self) { + PyTypeObject *type = Py_TYPE(self); PyObject_GC_UnTrack(self); treebuilder_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + type->tp_free((PyObject *)self); + if((void *)type == (void *)treebuilder_dealloc) { + Py_DECREF(type); + } } /* -------------------------------------------------------------------- */ @@ -2209,7 +2219,7 @@ } else { if (self->root) { PyErr_SetString( - elementtree_parseerror_obj, + _elementtreestate_global->elementtree_parseerror_obj, "multiple elements on top level" ); goto error; @@ -2451,48 +2461,26 @@ {NULL, NULL} }; -static PyTypeObject TreeBuilder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "TreeBuilder", sizeof(TreeBuilderObject), 0, - /* methods */ - (destructor)treebuilder_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ +static PyType_Slot TreeBuilder_Type_slots[] = { + {Py_tp_dealloc, (destructor)treebuilder_dealloc}, + {Py_tp_traverse, (traverseproc)treebuilder_gc_traverse}, + {Py_tp_clear, (inquiry)treebuilder_gc_clear}, + {Py_tp_methods, treebuilder_methods}, + {Py_tp_init, (initproc)treebuilder_init}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, treebuilder_new}, + {0, 0} +}; + +static PyType_Spec TreeBuilder_Type_spec = { + "TreeBuilder", + sizeof(TreeBuilderObject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)treebuilder_gc_traverse, /* tp_traverse */ - (inquiry)treebuilder_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - treebuilder_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)treebuilder_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - treebuilder_new, /* tp_new */ - 0, /* tp_free */ + TreeBuilder_Type_slots, }; + /* ==================================================================== */ /* the expat interface */ @@ -2528,9 +2516,8 @@ } XMLParserObject; -static PyTypeObject XMLParser_Type; - -#define XMLParser_CheckExact(op) (Py_TYPE(op) == &XMLParser_Type) + +#define XMLParser_CheckExact(op) (Py_TYPE(op) == (PyTypeObject *)_elementtreestate_global->XMLParser_Type) /* helpers */ @@ -2614,7 +2601,7 @@ if (errmsg == NULL) return; - error = PyObject_CallFunction(elementtree_parseerror_obj, "O", errmsg); + error = PyObject_CallFunction(_elementtreestate_global->elementtree_parseerror_obj, "O", errmsg); Py_DECREF(errmsg); if (!error) return; @@ -2644,7 +2631,7 @@ } Py_DECREF(position); - PyErr_SetObject(elementtree_parseerror_obj, error); + PyErr_SetObject(_elementtreestate_global->elementtree_parseerror_obj, error); Py_DECREF(error); } @@ -2995,6 +2982,7 @@ { XMLParserObject *self = (XMLParserObject *)type->tp_alloc(type, 0); if (self) { + Py_INCREF(type); self->parser = NULL; self->target = self->entity = self->names = NULL; self->handle_start = self->handle_data = self->handle_end = NULL; @@ -3038,7 +3026,7 @@ if (target) { Py_INCREF(target); } else { - target = treebuilder_new(&TreeBuilder_Type, NULL, NULL); + target = treebuilder_new((PyTypeObject *)_elementtreestate_global->TreeBuilder_Type, NULL, NULL); if (!target) { Py_CLEAR(self_xp->entity); Py_CLEAR(self_xp->names); @@ -3057,7 +3045,7 @@ self_xp->handle_doctype = PyObject_GetAttrString(target, "doctype"); PyErr_Clear(); - + /* configure parser */ EXPAT(SetUserData)(self_xp->parser, self_xp); EXPAT(SetElementHandler)( @@ -3135,9 +3123,13 @@ static void xmlparser_dealloc(XMLParserObject* self) { + PyTypeObject *type = Py_TYPE(self); PyObject_GC_UnTrack(self); xmlparser_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + type->tp_free((PyObject *)self); + if((void *)type->tp_dealloc == (void *)xmlparser_dealloc) { + Py_DECREF(type); + } } LOCAL(PyObject*) @@ -3413,48 +3405,27 @@ return PyObject_GenericGetAttr((PyObject*) self, nameobj); } -static PyTypeObject XMLParser_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "XMLParser", sizeof(XMLParserObject), 0, - /* methods */ - (destructor)xmlparser_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - (getattrofunc)xmlparser_getattro, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ +static PyType_Slot XMLParser_Type_slots[] = { + {Py_tp_dealloc, (destructor)xmlparser_dealloc}, + {Py_tp_getattro, (getattrofunc)xmlparser_getattro}, + {Py_tp_traverse, (traverseproc)xmlparser_gc_traverse}, + {Py_tp_clear, (inquiry)xmlparser_gc_clear}, + {Py_tp_methods, xmlparser_methods}, + {Py_tp_init, (initproc)xmlparser_init}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, xmlparser_new}, + {0, 0} +}; + +static PyType_Spec XMLParser_Type_spec = { + "XMLParser", + sizeof(XMLParserObject), + 0, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)xmlparser_gc_traverse, /* tp_traverse */ - (inquiry)xmlparser_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - xmlparser_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)xmlparser_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - xmlparser_new, /* tp_new */ - 0, /* tp_free */ + XMLParser_Type_slots, }; + #endif /* ==================================================================== */ @@ -3470,12 +3441,12 @@ PyModuleDef_HEAD_INIT, "_elementtree", NULL, - -1, + sizeof(_elementtreestate), _functions, NULL, - NULL, - NULL, - NULL + _elementtree_traverse, + _elementtree_clear, + _elementtree_free }; PyMODINIT_FUNC @@ -3483,26 +3454,45 @@ { PyObject *m, *temp; - /* Initialize object types */ - if (PyType_Ready(&TreeBuilder_Type) < 0) - return NULL; - if (PyType_Ready(&Element_Type) < 0) - return NULL; -#if defined(USE_EXPAT) - if (PyType_Ready(&XMLParser_Type) < 0) - return NULL; -#endif + m = PyState_FindModule(&_elementtreemodule); + if(m) { + Py_INCREF(m); + return m; + } m = PyModule_Create(&_elementtreemodule); if (!m) return NULL; + _elementtreestate(m)->ElementIter_Type = PyType_FromSpec(&ElementIter_Type_spec); + if (_elementtreestate(m)->ElementIter_Type == NULL) + return NULL; + + /* initialize object types */ + + _elementtreestate(m)->TreeBuilder_Type = PyType_FromSpec(&TreeBuilder_Type_spec); + if (_elementtreestate(m)->TreeBuilder_Type == NULL) + return NULL; + + _elementtreestate(m)->Element_Type = PyType_FromSpec(&Element_Type_spec); + if (_elementtreestate(m)->Element_Type == NULL) + return NULL; + + ((PyTypeObject *)(_elementtreestate(m)->Element_Type))->tp_weaklistoffset = \ + offsetof(ElementObject, weakreflist); + +#if defined(USE_EXPAT) + _elementtreestate(m)->XMLParser_Type = PyType_FromSpec(&XMLParser_Type_spec); + if (_elementtreestate(m)->XMLParser_Type == NULL) + return NULL; +#endif + if (!(temp = PyImport_ImportModule("copy"))) return NULL; - elementtree_deepcopy_obj = PyObject_GetAttrString(temp, "deepcopy"); + _elementtreestate(m)->elementtree_deepcopy_obj = PyObject_GetAttrString(temp, "deepcopy"); Py_XDECREF(temp); - if (!(elementpath_obj = PyImport_ImportModule("xml.etree.ElementPath"))) + if (!(_elementtreestate(m)->elementpath_obj = PyImport_ImportModule("xml.etree.ElementPath"))) return NULL; /* link against pyexpat */ @@ -3522,21 +3512,21 @@ return NULL; } - elementtree_parseerror_obj = PyErr_NewException( + _elementtreestate(m)->elementtree_parseerror_obj = PyErr_NewException( "xml.etree.ElementTree.ParseError", PyExc_SyntaxError, NULL ); - Py_INCREF(elementtree_parseerror_obj); - PyModule_AddObject(m, "ParseError", elementtree_parseerror_obj); - - Py_INCREF((PyObject *)&Element_Type); - PyModule_AddObject(m, "Element", (PyObject *)&Element_Type); - - Py_INCREF((PyObject *)&TreeBuilder_Type); - PyModule_AddObject(m, "TreeBuilder", (PyObject *)&TreeBuilder_Type); + Py_INCREF(_elementtreestate(m)->elementtree_parseerror_obj); + PyModule_AddObject(m, "ParseError", _elementtreestate(m)->elementtree_parseerror_obj); + + Py_INCREF(_elementtreestate(m)->Element_Type); + PyModule_AddObject(m, "Element", _elementtreestate(m)->Element_Type); + + Py_INCREF(_elementtreestate(m)->TreeBuilder_Type); + PyModule_AddObject(m, "TreeBuilder", _elementtreestate(m)->TreeBuilder_Type); #if defined(USE_EXPAT) - Py_INCREF((PyObject *)&XMLParser_Type); - PyModule_AddObject(m, "XMLParser", (PyObject *)&XMLParser_Type); + Py_INCREF(_elementtreestate(m)->XMLParser_Type); + PyModule_AddObject(m, "XMLParser", _elementtreestate(m)->XMLParser_Type); #endif return m; diff -r 3ca4bfca3039 Python/Python-ast.c --- a/Python/Python-ast.c Fri Dec 14 17:29:31 2012 +0100 +++ b/Python/Python-ast.c Fri Dec 14 17:31:38 2012 +0100 @@ -2066,7 +2066,6 @@ *arena) { expr_ty p; - assert(PyUnicode_CompareWithASCIIString(id, "True") && PyUnicode_CompareWithASCIIString(id, "False") && PyUnicode_CompareWithASCIIString(id, "None")); if (!id) { PyErr_SetString(PyExc_ValueError, "field id is required for Name");