diff -r af1f51cbbc34 Modules/unicodedata.c --- a/Modules/unicodedata.c Thu Aug 16 23:34:47 2012 +0200 +++ b/Modules/unicodedata.c Thu Aug 16 23:44:25 2012 +0200 @@ -72,16 +72,47 @@ {NULL} }; +typedef struct { + PyObject *UCD_Type; +} unicodedatastate; + + +#define unicodedata_state(o) ((unicodedatastate *)PyModule_GetState(o)) + +static int +unicodedata_clear(PyObject *m) +{ + Py_CLEAR(unicodedata_state(m)->UCD_Type); + return 0; +} + +static int +unicodedata_traverse(PyObject *m, visitproc visit, void *arg) +{ + Py_VISIT(unicodedata_state(m)->UCD_Type); + return 0; +} + +static void +unicodedata_free(void *m) +{ + unicodedata_clear((PyObject *)m); +} + /* forward declaration */ -static PyTypeObject UCD_Type; -#define UCD_Check(o) (Py_TYPE(o)==&UCD_Type) +static PyModuleDef unicodedatamodule; + +#define unicodedatastate_global ((unicodedatastate *)PyModule_GetState(PyState_FindModule(&unicodedatamodule))) + +#define UCD_Check(o) (Py_TYPE(o)==(PyTypeObject *)unicodedatastate_global->UCD_Type) static PyObject* new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4), Py_UCS4 (*normalization)(Py_UCS4)) { PreviousDBVersion *self; - self = PyObject_New(PreviousDBVersion, &UCD_Type); + self = PyObject_New(PreviousDBVersion, + (PyTypeObject *)unicodedatastate_global->UCD_Type); if (self == NULL) return NULL; self->name = name; @@ -1272,52 +1303,26 @@ {NULL, NULL} /* sentinel */ }; -static PyTypeObject UCD_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyVarObject_HEAD_INIT(NULL, 0) - "unicodedata.UCD", /*tp_name*/ - sizeof(PreviousDBVersion), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PyObject_Del, /*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*/ - PyObject_GenericGetAttr,/*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - unicodedata_functions, /*tp_methods*/ - DB_members, /*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*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ +/* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + +static PyType_Slot UCD_Type_slots[] = { + {Py_tp_dealloc, (destructor)PyObject_Del}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_methods, unicodedata_functions}, + {Py_tp_members, DB_members}, + {0, 0} }; +static PyType_Spec UCD_Type_spec = { + "unicodedata.UCD", + sizeof(PreviousDBVersion), + 0, + Py_TPFLAGS_DEFAULT, + UCD_Type_slots, +}; + + PyDoc_STRVAR(unicodedata_docstring, "This module provides access to the Unicode Character Database which\n\ defines character properties for all Unicode characters. The data in\n\ @@ -1333,12 +1338,12 @@ PyModuleDef_HEAD_INIT, "unicodedata", unicodedata_docstring, - -1, + sizeof(unicodedatastate), unicodedata_functions, NULL, - NULL, - NULL, - NULL + unicodedata_traverse, + unicodedata_clear, + unicodedata_free }; PyMODINIT_FUNC @@ -1346,15 +1351,18 @@ { PyObject *m, *v; - Py_TYPE(&UCD_Type) = &PyType_Type; - m = PyModule_Create(&unicodedatamodule); if (!m) return NULL; + PyState_AddModule(m, &unicodedatamodule); PyModule_AddStringConstant(m, "unidata_version", UNIDATA_VERSION); - Py_INCREF(&UCD_Type); - PyModule_AddObject(m, "UCD", (PyObject*)&UCD_Type); + + unicodedata_state(m)->UCD_Type = PyType_FromSpec(&UCD_Type_spec); + if(unicodedata_state(m)->UCD_Type == NULL) + return NULL; + Py_INCREF(unicodedata_state(m)->UCD_Type); + PyModule_AddObject(m, "UCD", unicodedata_state(m)->UCD_Type); /* Previous versions */ v = new_previous_version("3.2.0", get_change_3_2_0, normalization_3_2_0);