diff options
author | Victor Stinner <vstinner@python.org> | 2020-10-26 23:19:22 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-26 23:19:22 +0100 |
commit | c8c4200b65b2159bbb13cee10d67dfb3676fef26 (patch) | |
tree | f34af496fa9843ccc7b1bc596e26b8adf000fe1d /Modules/unicodedata.c | |
parent | bpo-42157: unicodedata avoids references to UCD_Type (GH-22990) (diff) | |
download | cpython-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.c | 120 |
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); } |