]> granicus.if.org Git - python/commitdiff
bpo-38073: Make pwd module PEP-384 compatible (GH-15790)
authorDino Viehland <dinoviehland@fb.com>
Tue, 10 Sep 2019 12:59:43 +0000 (13:59 +0100)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 10 Sep 2019 12:59:43 +0000 (05:59 -0700)
Makes the pwd module PEP-384 compatible

https://bugs.python.org/issue38073

Automerge-Triggered-By: @tiran
Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-17-58.bpo-38073.ZoKYOU.rst [new file with mode: 0644]
Modules/pwdmodule.c

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 (file)
index 0000000..d59630f
--- /dev/null
@@ -0,0 +1 @@
+Make pwd extension module PEP-384 compatible
index e0232b8d589baa844f40b21ceda194ac1c20871e..b5ef2557db77d938a0f36f6d2cd634d488cddedb 100644 (file)
@@ -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;
 }