diff --git a/Misc/NEWS.d/next/C API/2020-11-18-09-46-35.bpo-1635741.SH8OIT.rst b/Misc/NEWS.d/next/C API/2020-11-18-09-46-35.bpo-1635741.SH8OIT.rst new file mode 100644 index 00000000000..34802cd9d3a --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-11-18-09-46-35.bpo-1635741.SH8OIT.rst @@ -0,0 +1,2 @@ +Port :mod:`grp` and :mod:`pwd` extension modules to multiphase +initialization (:pep:`489`) diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index c4d16819e48..f6298ca0ee8 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -46,20 +46,19 @@ get_grp_state(PyObject *module) return (grpmodulestate *)state; } -#define modulestate_global get_grp_state(PyState_FindModule(&grpmodule)) - static struct PyModuleDef grpmodule; #define DEFAULT_BUFFER_SIZE 1024 static PyObject * -mkgrent(struct group *p) +mkgrent(PyObject *module, struct group *p) { int setIndex = 0; PyObject *v, *w; char **member; - if ((v = PyStructSequence_New(modulestate_global->StructGrpType)) == NULL) + v = PyStructSequence_New(get_grp_state(module)->StructGrpType); + if (v == NULL) return NULL; if ((w = PyList_New(0)) == NULL) { @@ -170,7 +169,7 @@ grp_getgrgid_impl(PyObject *module, PyObject *id) Py_DECREF(gid_obj); return NULL; } - retval = mkgrent(p); + retval = mkgrent(module, p); #ifdef HAVE_GETGRGID_R PyMem_RawFree(buf); #endif @@ -248,7 +247,7 @@ grp_getgrnam_impl(PyObject *module, PyObject *name) } goto out; } - retval = mkgrent(p); + retval = mkgrent(module, p); out: PyMem_RawFree(buf); Py_DECREF(bytes); @@ -275,7 +274,7 @@ grp_getgrall_impl(PyObject *module) return NULL; setgrent(); while ((p = getgrent()) != NULL) { - PyObject *v = mkgrent(p); + PyObject *v = mkgrent(module, p); if (v == NULL || PyList_Append(d, v) != 0) { Py_XDECREF(v); Py_DECREF(d); @@ -311,6 +310,26 @@ users are not explicitly listed as members of the groups they are in\n\ according to the password database. Check both databases to get\n\ complete membership information.)"); +static int +grpmodule_exec(PyObject *module) +{ + grpmodulestate *state = get_grp_state(module); + + state->StructGrpType = PyStructSequence_NewType(&struct_group_type_desc); + if (state->StructGrpType == NULL) { + return -1; + } + if (PyModule_AddType(module, state->StructGrpType) < 0) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot grpmodule_slots[] = { + {Py_mod_exec, grpmodule_exec}, + {0, NULL} +}; + static int grpmodule_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(get_grp_state(m)->StructGrpType); return 0; @@ -326,37 +345,19 @@ static void grpmodule_free(void *m) { } static struct PyModuleDef grpmodule = { - PyModuleDef_HEAD_INIT, - "grp", - grp__doc__, - sizeof(grpmodulestate), - grp_methods, - NULL, - grpmodule_traverse, - grpmodule_clear, - grpmodule_free, + PyModuleDef_HEAD_INIT, + .m_name = "grp", + .m_doc = grp__doc__, + .m_size = sizeof(grpmodulestate), + .m_methods = grp_methods, + .m_slots = grpmodule_slots, + .m_traverse = grpmodule_traverse, + .m_clear = grpmodule_clear, + .m_free = grpmodule_free, }; PyMODINIT_FUNC PyInit_grp(void) { - PyObject *m; - if ((m = PyState_FindModule(&grpmodule)) != NULL) { - Py_INCREF(m); - return m; - } - - if ((m = PyModule_Create(&grpmodule)) == NULL) { - return NULL; - } - - grpmodulestate *state = PyModule_GetState(m); - state->StructGrpType = PyStructSequence_NewType(&struct_group_type_desc); - if (state->StructGrpType == NULL) { - return NULL; - } - - Py_INCREF(state->StructGrpType); - PyModule_AddObject(m, "struct_group", (PyObject *) state->StructGrpType); - return m; + return PyModuleDef_Init(&grpmodule); } diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index 901a3ed9a2e..14d3f9dcb1c 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -59,8 +59,6 @@ get_pwd_state(PyObject *module) return (pwdmodulestate *)state; } -#define modulestate_global get_pwd_state(PyState_FindModule(&pwdmodule)) - static struct PyModuleDef pwdmodule; #define DEFAULT_BUFFER_SIZE 1024 @@ -79,10 +77,10 @@ sets(PyObject *v, int i, const char* val) } static PyObject * -mkpwent(struct passwd *p) +mkpwent(PyObject *module, struct passwd *p) { int setIndex = 0; - PyObject *v = PyStructSequence_New(modulestate_global->StructPwdType); + PyObject *v = PyStructSequence_New(get_pwd_state(module)->StructPwdType); if (v == NULL) return NULL; @@ -194,7 +192,7 @@ pwd_getpwuid(PyObject *module, PyObject *uidobj) Py_DECREF(uid_obj); return NULL; } - retval = mkpwent(p); + retval = mkpwent(module, p); #ifdef HAVE_GETPWUID_R PyMem_RawFree(buf); #endif @@ -274,7 +272,7 @@ pwd_getpwnam_impl(PyObject *module, PyObject *name) } goto out; } - retval = mkpwent(p); + retval = mkpwent(module, p); out: PyMem_RawFree(buf); Py_DECREF(bytes); @@ -300,7 +298,7 @@ pwd_getpwall_impl(PyObject *module) return NULL; setpwent(); while ((p = getpwent()) != NULL) { - PyObject *v = mkpwent(p); + PyObject *v = mkpwent(module, p); if (v == NULL || PyList_Append(d, v) != 0) { Py_XDECREF(v); Py_DECREF(d); @@ -323,6 +321,26 @@ static PyMethodDef pwd_methods[] = { {NULL, NULL} /* sentinel */ }; +static int +pwdmodule_exec(PyObject *module) +{ + pwdmodulestate *state = get_pwd_state(module); + + state->StructPwdType = PyStructSequence_NewType(&struct_pwd_type_desc); + if (state->StructPwdType == NULL) { + return -1; + } + if (PyModule_AddType(module, state->StructPwdType) < 0) { + return -1; + } + return 0; +} + +static PyModuleDef_Slot pwdmodule_slots[] = { + {Py_mod_exec, pwdmodule_exec}, + {0, NULL} +}; + static int pwdmodule_traverse(PyObject *m, visitproc visit, void *arg) { Py_VISIT(get_pwd_state(m)->StructPwdType); return 0; @@ -337,34 +355,19 @@ static void pwdmodule_free(void *m) { static struct PyModuleDef pwdmodule = { PyModuleDef_HEAD_INIT, - "pwd", - pwd__doc__, - sizeof(pwdmodulestate), - pwd_methods, - NULL, - pwdmodule_traverse, - pwdmodule_clear, - pwdmodule_free, + .m_name = "pwd", + .m_doc = pwd__doc__, + .m_size = sizeof(pwdmodulestate), + .m_methods = pwd_methods, + .m_slots = pwdmodule_slots, + .m_traverse = pwdmodule_traverse, + .m_clear = pwdmodule_clear, + .m_free = pwdmodule_free, }; PyMODINIT_FUNC PyInit_pwd(void) { - PyObject *m; - if ((m = PyState_FindModule(&pwdmodule)) != NULL) { - Py_INCREF(m); - return m; - } - if ((m = PyModule_Create(&pwdmodule)) == NULL) - return NULL; - - pwdmodulestate *state = PyModule_GetState(m); - state->StructPwdType = PyStructSequence_NewType(&struct_pwd_type_desc); - if (state->StructPwdType == NULL) { - return NULL; - } - Py_INCREF(state->StructPwdType); - PyModule_AddObject(m, "struct_passwd", (PyObject *) state->StructPwdType); - return m; + return PyModuleDef_Init(&pwdmodule); }