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 00000000000000..34802cd9d3af32 --- /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 c4d16819e487aa..f6298ca0ee84c1 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 901a3ed9a2e378..14d3f9dcb1c60f 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); }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: