From b7f8e52433b656a6a524229fd7a65e4682a43729 Mon Sep 17 00:00:00 2001 From: Dino Viehland Date: Tue, 10 Sep 2019 13:59:43 +0100 Subject: [PATCH] bpo-38073: Make pwd module PEP-384 compatible (GH-15790) Makes the pwd module PEP-384 compatible https://bugs.python.org/issue38073 Automerge-Triggered-By: @tiran --- .../2019-09-09-15-17-58.bpo-38073.ZoKYOU.rst | 1 + Modules/pwdmodule.c | 51 +++++++++++++------ 2 files changed, 36 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-17-58.bpo-38073.ZoKYOU.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-17-58.bpo-38073.ZoKYOU.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-17-58.bpo-38073.ZoKYOU.rst new file mode 100644 index 0000000000..d59630f888 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-17-58.bpo-38073.ZoKYOU.rst @@ -0,0 +1 @@ +Make pwd extension module PEP-384 compatible diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index e0232b8d58..b5ef2557db 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -47,8 +47,13 @@ The uid and gid items are integers, all others are strings. An\n\ exception is raised if the entry asked for cannot be found."); -static int initialized; -static PyTypeObject StructPwdType; +typedef struct { + PyTypeObject *StructPwdType; +} pwdmodulestate; +#define modulestate(o) ((pwdmodulestate *)PyModule_GetState(o)) +#define modulestate_global modulestate(PyState_FindModule(&pwdmodule)) + +static struct PyModuleDef pwdmodule; #define DEFAULT_BUFFER_SIZE 1024 @@ -69,7 +74,7 @@ static PyObject * mkpwent(struct passwd *p) { int setIndex = 0; - PyObject *v = PyStructSequence_New(&StructPwdType); + PyObject *v = PyStructSequence_New(modulestate_global->StructPwdType); if (v == NULL) return NULL; @@ -310,16 +315,28 @@ static PyMethodDef pwd_methods[] = { {NULL, NULL} /* sentinel */ }; +static int pwdmodule_traverse(PyObject *m, visitproc visit, void *arg) { + Py_VISIT(modulestate(m)->StructPwdType); + return 0; +} +static int pwdmodule_clear(PyObject *m) { + Py_CLEAR(modulestate(m)->StructPwdType); + return 0; +} +static void pwdmodule_free(void *m) { + pwdmodule_clear((PyObject *)m); +} + static struct PyModuleDef pwdmodule = { PyModuleDef_HEAD_INIT, "pwd", pwd__doc__, - -1, + sizeof(pwdmodulestate), pwd_methods, NULL, - NULL, - NULL, - NULL + pwdmodule_traverse, + pwdmodule_clear, + pwdmodule_free, }; @@ -327,17 +344,19 @@ PyMODINIT_FUNC PyInit_pwd(void) { PyObject *m; - m = PyModule_Create(&pwdmodule); - if (m == NULL) + if ((m = PyState_FindModule(&pwdmodule)) != NULL) { + Py_INCREF(m); + return m; + } + if ((m = PyModule_Create(&pwdmodule)) == NULL) return NULL; - if (!initialized) { - if (PyStructSequence_InitType2(&StructPwdType, - &struct_pwd_type_desc) < 0) - return NULL; - initialized = 1; + pwdmodulestate *state = PyModule_GetState(m); + state->StructPwdType = PyStructSequence_NewType(&struct_pwd_type_desc); + if (state->StructPwdType == NULL) { + return NULL; } - Py_INCREF((PyObject *) &StructPwdType); - PyModule_AddObject(m, "struct_passwd", (PyObject *) &StructPwdType); + Py_INCREF(state->StructPwdType); + PyModule_AddObject(m, "struct_passwd", (PyObject *) state->StructPwdType); return m; } -- 2.40.0