bpo-42157: Convert unicodedata.UCD to heap type (GH-22991)

Convert the unicodedata extension module to the multiphase
initialization API (PEP 489) and convert the unicodedata.UCD static
type to a heap type.

Co-Authored-By: Mohamed Koubaa <koubaa.m@gmail.com>
This commit is contained in:
Victor Stinner 2020-10-26 23:19:22 +01:00 committed by GitHub
parent 920cb647ba
commit c8c4200b65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 84 deletions

View File

@ -0,0 +1,4 @@
Convert the :mod:`unicodedata` extension module to the multiphase
initialization API (:pep:`489`) and convert the ``unicodedata.UCD``
static type to a heap type.
Patch by Mohamed Koubaa and Victor Stinner.

View File

@ -891,14 +891,14 @@ static PyModuleDef_Slot _abcmodule_slots[] = {
static struct PyModuleDef _abcmodule = { static struct PyModuleDef _abcmodule = {
PyModuleDef_HEAD_INIT, PyModuleDef_HEAD_INIT,
"_abc", .m_name = "_abc",
_abc__doc__, .m_doc = _abc__doc__,
sizeof(_abcmodule_state), .m_size = sizeof(_abcmodule_state),
_abcmodule_methods, .m_methods = _abcmodule_methods,
_abcmodule_slots, .m_slots = _abcmodule_slots,
_abcmodule_traverse, .m_traverse = _abcmodule_traverse,
_abcmodule_clear, .m_clear = _abcmodule_clear,
_abcmodule_free, .m_free = _abcmodule_free,
}; };
PyMODINIT_FUNC PyMODINIT_FUNC

View File

@ -28,9 +28,9 @@ _Py_IDENTIFIER(NFKD);
/*[clinic input] /*[clinic input]
module unicodedata module unicodedata
class unicodedata.UCD 'PreviousDBVersion *' '&UCD_Type' class unicodedata.UCD 'PreviousDBVersion *' '<not used>'
[clinic start generated code]*/ [clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6dac153082d150bc]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=e47113e05924be43]*/
/* character properties */ /* character properties */
@ -90,9 +90,6 @@ static PyMemberDef DB_members[] = {
{NULL} {NULL}
}; };
/* forward declaration */
static PyTypeObject UCD_Type;
// Check if self is an unicodedata.UCD instance. // Check if self is an unicodedata.UCD instance.
// If self is NULL (when the PyCapsule C API is used), return 0. // If self is NULL (when the PyCapsule C API is used), return 0.
// PyModule_Check() is used to avoid having to retrieve the ucd_type. // PyModule_Check() is used to avoid having to retrieve the ucd_type.
@ -1417,50 +1414,27 @@ static PyMethodDef unicodedata_functions[] = {
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
static PyTypeObject UCD_Type = { static void
/* The ob_type field must be initialized in the module init function ucd_dealloc(PreviousDBVersion *self)
* to be portable to Windows without using C++. */ {
PyVarObject_HEAD_INIT(NULL, 0) PyTypeObject *tp = Py_TYPE(self);
"unicodedata.UCD", /*tp_name*/ PyObject_Del(self);
sizeof(PreviousDBVersion), /*tp_basicsize*/ Py_DECREF(tp);
0, /*tp_itemsize*/ }
/* methods */
(destructor)PyObject_Del, /*tp_dealloc*/ static PyType_Slot ucd_type_slots[] = {
0, /*tp_vectorcall_offset*/ {Py_tp_dealloc, ucd_dealloc},
0, /*tp_getattr*/ {Py_tp_getattro, PyObject_GenericGetAttr},
0, /*tp_setattr*/ {Py_tp_methods, unicodedata_functions},
0, /*tp_as_async*/ {Py_tp_members, DB_members},
0, /*tp_repr*/ {0, 0}
0, /*tp_as_number*/ };
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/ static PyType_Spec ucd_type_spec = {
0, /*tp_hash*/ .name = "unicodedata.UCD",
0, /*tp_call*/ .basicsize = sizeof(PreviousDBVersion),
0, /*tp_str*/ .flags = Py_TPFLAGS_DEFAULT,
PyObject_GenericGetAttr,/*tp_getattro*/ .slots = ucd_type_slots
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*/
}; };
PyDoc_STRVAR(unicodedata_docstring, PyDoc_STRVAR(unicodedata_docstring,
@ -1472,30 +1446,20 @@ this database is based on the UnicodeData.txt file version\n\
The module uses the same names and symbols as defined by the\n\ The module uses the same names and symbols as defined by the\n\
UnicodeData File Format " UNIDATA_VERSION "."); UnicodeData File Format " UNIDATA_VERSION ".");
static struct PyModuleDef unicodedatamodule = {
PyModuleDef_HEAD_INIT,
"unicodedata",
unicodedata_docstring,
-1,
unicodedata_functions,
NULL,
NULL,
NULL,
NULL
};
static int static int
unicodedata_exec(PyObject *module) unicodedata_exec(PyObject *module)
{ {
Py_SET_TYPE(&UCD_Type, &PyType_Type);
PyTypeObject *ucd_type = &UCD_Type;
if (PyModule_AddStringConstant(module, "unidata_version", UNIDATA_VERSION) < 0) { if (PyModule_AddStringConstant(module, "unidata_version", UNIDATA_VERSION) < 0) {
return -1; return -1;
} }
PyTypeObject *ucd_type = (PyTypeObject *)PyType_FromSpec(&ucd_type_spec);
if (ucd_type == NULL) {
return -1;
}
if (PyModule_AddType(module, ucd_type) < 0) { if (PyModule_AddType(module, ucd_type) < 0) {
Py_DECREF(ucd_type);
return -1; return -1;
} }
@ -1503,6 +1467,7 @@ unicodedata_exec(PyObject *module)
PyObject *v; PyObject *v;
v = new_previous_version(ucd_type, "3.2.0", v = new_previous_version(ucd_type, "3.2.0",
get_change_3_2_0, normalization_3_2_0); get_change_3_2_0, normalization_3_2_0);
Py_DECREF(ucd_type);
if (v == NULL) { if (v == NULL) {
return -1; return -1;
} }
@ -1524,21 +1489,24 @@ unicodedata_exec(PyObject *module)
return 0; return 0;
} }
static PyModuleDef_Slot unicodedata_slots[] = {
{Py_mod_exec, unicodedata_exec},
{0, NULL}
};
static struct PyModuleDef unicodedata_module = {
PyModuleDef_HEAD_INIT,
.m_name = "unicodedata",
.m_doc = unicodedata_docstring,
.m_size = 0,
.m_methods = unicodedata_functions,
.m_slots = unicodedata_slots,
};
PyMODINIT_FUNC PyMODINIT_FUNC
PyInit_unicodedata(void) PyInit_unicodedata(void)
{ {
PyObject *module = PyModule_Create(&unicodedatamodule); return PyModuleDef_Init(&unicodedata_module);
if (!module) {
return NULL;
}
if (unicodedata_exec(module) < 0) {
Py_DECREF(module);
return NULL;
}
return module;
} }