diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-03-24-22-26-26.bpo-1635741.AB38ot.rst b/Misc/NEWS.d/next/Core and Builtins/2020-03-24-22-26-26.bpo-1635741.AB38ot.rst new file mode 100644 index 00000000000..1a611628343 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-03-24-22-26-26.bpo-1635741.AB38ot.rst @@ -0,0 +1,2 @@ +Port _functools module to multiphase initialization (PEP 489). Patch by +Paulo Henrique Silva. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index ff733b8d45a..2e27d48b147 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -1400,10 +1400,10 @@ static PyTypeObject lru_cache_type = { /* module level code ********************************************************/ -PyDoc_STRVAR(module_doc, +PyDoc_STRVAR(_functools_doc, "Tools that operate on functions."); -static PyMethodDef module_methods[] = { +static PyMethodDef _functools_methods[] = { {"reduce", functools_reduce, METH_VARARGS, functools_reduce_doc}, {"cmp_to_key", (PyCFunction)(void(*)(void))functools_cmp_to_key, METH_VARARGS | METH_KEYWORDS, functools_cmp_to_key_doc}, @@ -1411,47 +1411,51 @@ static PyMethodDef module_methods[] = { }; static void -module_free(void *m) +_functools_free(void *m) { Py_CLEAR(kwd_mark); } -static struct PyModuleDef _functoolsmodule = { - PyModuleDef_HEAD_INIT, - "_functools", - module_doc, - -1, - module_methods, - NULL, - NULL, - NULL, - module_free, -}; - -PyMODINIT_FUNC -PyInit__functools(void) +static int +_functools_exec(PyObject *module) { - PyObject *m; PyTypeObject *typelist[] = { &partial_type, &lru_cache_type }; - m = PyModule_Create(&_functoolsmodule); - if (m == NULL) - return NULL; - kwd_mark = _PyObject_CallNoArg((PyObject *)&PyBaseObject_Type); if (!kwd_mark) { - Py_DECREF(m); - return NULL; + return -1; } for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { - if (PyModule_AddType(m, typelist[i]) < 0) { - Py_DECREF(m); - return NULL; + if (PyModule_AddType(module, typelist[i]) < 0) { + return -1; } } - return m; + return 0; +} + +static struct PyModuleDef_Slot _functools_slots[] = { + {Py_mod_exec, _functools_exec}, + {0, NULL} +}; + +static struct PyModuleDef _functools_module = { + PyModuleDef_HEAD_INIT, + "_functools", + _functools_doc, + 0, + _functools_methods, + _functools_slots, + NULL, + NULL, + _functools_free, +}; + +PyMODINIT_FUNC +PyInit__functools(void) +{ + return PyModuleDef_Init(&_functools_module); }