diff -r e55ea9f5986f Modules/pyexpat.c --- a/Modules/pyexpat.c Thu Aug 16 21:52:38 2012 +0200 +++ b/Modules/pyexpat.c Thu Aug 16 21:53:00 2012 +0200 @@ -37,8 +37,40 @@ #endif _DummyDecl }; +typedef struct { + PyObject *ErrorObject; + PyObject *Xmlparsetype; +} pyexpatstate; -static PyObject *ErrorObject; + +#define pyexpat_state(o) ((pyexpatstate *)PyModule_GetState(o)) + +static int +pyexpat_clear(PyObject *m) +{ + Py_CLEAR(pyexpat_state(m)->ErrorObject); + Py_CLEAR(pyexpat_state(m)->Xmlparsetype); + return 0; +} + +static int +pyexpat_traverse(PyObject *m, visitproc visit, void *arg) +{ + Py_VISIT(pyexpat_state(m)->ErrorObject); + Py_VISIT(pyexpat_state(m)->Xmlparsetype); + return 0; +} + +static void +pyexpat_free(void *m) +{ + pyexpat_clear((PyObject *)m); +} + +static PyModuleDef pyexpatmodule; + +#define pyexpatstate_global ((pyexpatstate *)PyModule_GetState(PyState_FindModule(&pyexpatmodule))) + /* ----------------------------------------------------- */ @@ -62,8 +94,6 @@ #define CHARACTER_DATA_BUFFER_SIZE 8192 -static PyTypeObject Xmlparsetype; - typedef void (*xmlhandlersetter)(XML_Parser self, void *meth); typedef void* xmlhandler; @@ -109,13 +139,13 @@ XML_ErrorString(code), lineno, column); if (buffer == NULL) return NULL; - err = PyObject_CallFunction(ErrorObject, "O", buffer); + err = PyObject_CallFunction(pyexpatstate_global->ErrorObject, "O", buffer); Py_DECREF(buffer); if ( err != NULL && set_error_attr(err, "code", code) && set_error_attr(err, "offset", column) && set_error_attr(err, "lineno", lineno)) { - PyErr_SetObject(ErrorObject, err); + PyErr_SetObject(pyexpatstate_global->ErrorObject, err); } Py_XDECREF(err); return NULL; @@ -947,7 +977,8 @@ return NULL; } - new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype); + new_parser = PyObject_GC_New(xmlparseobject, + (PyTypeObject *)pyexpatstate_global->Xmlparsetype); if (new_parser == NULL) return NULL; new_parser->buffer_size = self->buffer_size; @@ -999,6 +1030,7 @@ handler_info[i].handler); } } + Py_INCREF(pyexpatstate_global->Xmlparsetype); return (PyObject *)new_parser; } @@ -1138,7 +1170,8 @@ int i; xmlparseobject *self; - self = PyObject_GC_New(xmlparseobject, &Xmlparsetype); + self = PyObject_GC_New(xmlparseobject, + (PyTypeObject *)pyexpatstate_global->Xmlparsetype); if (self == NULL) return NULL; @@ -1185,7 +1218,8 @@ return PyErr_NoMemory(); } clear_handlers(self, 1); - + Py_INCREF(pyexpatstate_global->Xmlparsetype); + return (PyObject*)self; } @@ -1194,6 +1228,7 @@ xmlparse_dealloc(xmlparseobject *self) { int i; + PyTypeObject *type = Py_TYPE(self); PyObject_GC_UnTrack(self); if (self->itself != NULL) XML_ParserFree(self->itself); @@ -1214,6 +1249,9 @@ self->buffer = NULL; } Py_XDECREF(self->intern); + if((void *)type->tp_dealloc == (void *)xmlparse_dealloc) { + Py_DECREF(type); + } PyObject_GC_Del(self); } @@ -1524,38 +1562,29 @@ PyDoc_STRVAR(Xmlparsetype__doc__, "XML parser"); -static PyTypeObject Xmlparsetype = { - PyVarObject_HEAD_INIT(NULL, 0) - "pyexpat.xmlparser", /*tp_name*/ - sizeof(xmlparseobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)xmlparse_dealloc, /*tp_dealloc*/ - (printfunc)0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_reserved*/ - (reprfunc)0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - (hashfunc)0, /*tp_hash*/ - (ternaryfunc)0, /*tp_call*/ - (reprfunc)0, /*tp_str*/ - (getattrofunc)xmlparse_getattro, /* tp_getattro */ - (setattrofunc)xmlparse_setattro, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - Xmlparsetype__doc__, /* tp_doc - Documentation string */ - (traverseproc)xmlparse_traverse, /* tp_traverse */ - (inquiry)xmlparse_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - xmlparse_methods, /* tp_methods */ + + + +static PyType_Slot Xmlparsetype_slots[] = { + {Py_tp_dealloc, (destructor)xmlparse_dealloc}, + {Py_tp_getattro, (getattrofunc)xmlparse_getattro}, + {Py_tp_setattro, (setattrofunc)xmlparse_setattro}, + {Py_tp_doc, Xmlparsetype__doc__}, + {Py_tp_traverse, (traverseproc)xmlparse_traverse}, + {Py_tp_clear, (inquiry)xmlparse_clear}, + {Py_tp_methods, xmlparse_methods}, + {0, 0} }; +static PyType_Spec Xmlparsetype_spec = { + "pyexpat.xmlparser", + sizeof(xmlparseobject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + Xmlparsetype_slots, +}; + + /* End of code for xmlparser objects */ /* -------------------------------------------------------- */ @@ -1660,12 +1689,12 @@ PyModuleDef_HEAD_INIT, MODULE_NAME, pyexpat_module_documentation, - -1, + sizeof(pyexpatstate), pyexpat_methods, NULL, - NULL, - NULL, - NULL + pyexpat_traverse, + pyexpat_clear, + pyexpat_free }; PyMODINIT_FUNC @@ -1690,27 +1719,31 @@ if (modelmod_name == NULL) return NULL; - if (PyType_Ready(&Xmlparsetype) < 0) - return NULL; + m = PyState_FindModule(&pyexpatmodule); + if(m == NULL) { + /* Create the module and add the functions */ + m = PyModule_Create(&pyexpatmodule); + if (m == NULL) + return NULL; + } - /* Create the module and add the functions */ - m = PyModule_Create(&pyexpatmodule); - if (m == NULL) + pyexpat_state(m)->Xmlparsetype = PyType_FromSpec(&Xmlparsetype_spec); + if (pyexpat_state(m)->Xmlparsetype == NULL) return NULL; /* Add some symbolic constants to the module */ - if (ErrorObject == NULL) { - ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError", + if (pyexpat_state(m)->ErrorObject == NULL) { + pyexpat_state(m)->ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError", NULL, NULL); - if (ErrorObject == NULL) + if (pyexpat_state(m)->ErrorObject == NULL) return NULL; } - Py_INCREF(ErrorObject); - PyModule_AddObject(m, "error", ErrorObject); - Py_INCREF(ErrorObject); - PyModule_AddObject(m, "ExpatError", ErrorObject); - Py_INCREF(&Xmlparsetype); - PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); + Py_INCREF(pyexpat_state(m)->ErrorObject); + PyModule_AddObject(m, "error", pyexpat_state(m)->ErrorObject); + Py_INCREF(pyexpat_state(m)->ErrorObject); + PyModule_AddObject(m, "ExpatError", pyexpat_state(m)->ErrorObject); + Py_INCREF(pyexpat_state(m)->Xmlparsetype); + PyModule_AddObject(m, "XMLParserType", pyexpat_state(m)->Xmlparsetype); PyModule_AddStringConstant(m, "EXPAT_VERSION", (char *) XML_ExpatVersion());