aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-10-26 23:19:22 +0100
committerGitHub <noreply@github.com>2020-10-26 23:19:22 +0100
commitc8c4200b65b2159bbb13cee10d67dfb3676fef26 (patch)
treef34af496fa9843ccc7b1bc596e26b8adf000fe1d /Modules/unicodedata.c
parentbpo-42157: unicodedata avoids references to UCD_Type (GH-22990) (diff)
downloadcpython-c8c4200b65b2159bbb13cee10d67dfb3676fef26.tar.gz
cpython-c8c4200b65b2159bbb13cee10d67dfb3676fef26.tar.bz2
cpython-c8c4200b65b2159bbb13cee10d67dfb3676fef26.zip
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>
Diffstat (limited to 'Modules/unicodedata.c')
-rw-r--r--Modules/unicodedata.c120
1 files changed, 44 insertions, 76 deletions
diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c
index 6c802ba116f..18b0a9af9d2 100644
--- a/Modules/unicodedata.c
+++ b/Modules/unicodedata.c
@@ -28,9 +28,9 @@ _Py_IDENTIFIER(NFKD);
/*[clinic input]
module unicodedata
-class unicodedata.UCD 'PreviousDBVersion *' '&UCD_Type'
+class unicodedata.UCD 'PreviousDBVersion *' '<not used>'
[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6dac153082d150bc]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e47113e05924be43]*/
/* character properties */
@@ -90,9 +90,6 @@ static PyMemberDef DB_members[] = {
{NULL}
};
-/* forward declaration */
-static PyTypeObject UCD_Type;
-
// Check if self is an unicodedata.UCD instance.
// 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.
@@ -1417,50 +1414,27 @@ static PyMethodDef unicodedata_functions[] = {
{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_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_as_async*/
- 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*/
+static void
+ucd_dealloc(PreviousDBVersion *self)
+{
+ PyTypeObject *tp = Py_TYPE(self);
+ PyObject_Del(self);
+ Py_DECREF(tp);
+}
+
+static PyType_Slot ucd_type_slots[] = {
+ {Py_tp_dealloc, ucd_dealloc},
+ {Py_tp_getattro, PyObject_GenericGetAttr},
+ {Py_tp_methods, unicodedata_functions},
+ {Py_tp_members, DB_members},
+ {0, 0}
+};
+
+static PyType_Spec ucd_type_spec = {
+ .name = "unicodedata.UCD",
+ .basicsize = sizeof(PreviousDBVersion),
+ .flags = Py_TPFLAGS_DEFAULT,
+ .slots = ucd_type_slots
};
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\
UnicodeData File Format " UNIDATA_VERSION ".");
-static struct PyModuleDef unicodedatamodule = {
- PyModuleDef_HEAD_INIT,
- "unicodedata",
- unicodedata_docstring,
- -1,
- unicodedata_functions,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-
static int
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) {
return -1;
}
+ PyTypeObject *ucd_type = (PyTypeObject *)PyType_FromSpec(&ucd_type_spec);
+ if (ucd_type == NULL) {
+ return -1;
+ }
+
if (PyModule_AddType(module, ucd_type) < 0) {
+ Py_DECREF(ucd_type);
return -1;
}
@@ -1503,6 +1467,7 @@ unicodedata_exec(PyObject *module)
PyObject *v;
v = new_previous_version(ucd_type, "3.2.0",
get_change_3_2_0, normalization_3_2_0);
+ Py_DECREF(ucd_type);
if (v == NULL) {
return -1;
}
@@ -1524,21 +1489,24 @@ unicodedata_exec(PyObject *module)
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
PyInit_unicodedata(void)
{
- PyObject *module = PyModule_Create(&unicodedatamodule);
- if (!module) {
- return NULL;
- }
-
- if (unicodedata_exec(module) < 0) {
- Py_DECREF(module);
- return NULL;
- }
-
- return module;
+ return PyModuleDef_Init(&unicodedata_module);
}