bpo-1635741: Port spwd to multiphase initialization (GH-23390)

Signed-off-by: Christian Heimes <christian@python.org>
This commit is contained in:
Christian Heimes 2020-11-19 10:54:03 +01:00 committed by GitHub
parent 3094dd5fb5
commit bf9d70a1a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 27 deletions

View File

@ -0,0 +1 @@
Port :mod:`spwd` extension module to multiphase initialization (:pep:`489`)

View File

@ -59,9 +59,19 @@ static PyStructSequence_Desc struct_spwd_type_desc = {
9, 9,
}; };
static int initialized; typedef struct {
static PyTypeObject StructSpwdType; PyTypeObject *StructSpwdType;
} spwdmodulestate;
static inline spwdmodulestate*
get_spwd_state(PyObject *module)
{
void *state = PyModule_GetState(module);
assert(state != NULL);
return (spwdmodulestate *)state;
}
static struct PyModuleDef spwdmodule;
static void static void
sets(PyObject *v, int i, const char* val) sets(PyObject *v, int i, const char* val)
@ -75,10 +85,10 @@ sets(PyObject *v, int i, const char* val)
} }
} }
static PyObject *mkspent(struct spwd *p) static PyObject *mkspent(PyObject *module, struct spwd *p)
{ {
int setIndex = 0; int setIndex = 0;
PyObject *v = PyStructSequence_New(&StructSpwdType); PyObject *v = PyStructSequence_New(get_spwd_state(module)->StructSpwdType);
if (v == NULL) if (v == NULL)
return NULL; return NULL;
@ -144,7 +154,7 @@ spwd_getspnam_impl(PyObject *module, PyObject *arg)
PyErr_SetString(PyExc_KeyError, "getspnam(): name not found"); PyErr_SetString(PyExc_KeyError, "getspnam(): name not found");
goto out; goto out;
} }
retval = mkspent(p); retval = mkspent(module, p);
out: out:
Py_DECREF(bytes); Py_DECREF(bytes);
return retval; return retval;
@ -172,7 +182,7 @@ spwd_getspall_impl(PyObject *module)
return NULL; return NULL;
setspent(); setspent();
while ((p = getspent()) != NULL) { while ((p = getspent()) != NULL) {
PyObject *v = mkspent(p); PyObject *v = mkspent(module, p);
if (v == NULL || PyList_Append(d, v) != 0) { if (v == NULL || PyList_Append(d, v) != 0) {
Py_XDECREF(v); Py_XDECREF(v);
Py_DECREF(d); Py_DECREF(d);
@ -197,34 +207,54 @@ static PyMethodDef spwd_methods[] = {
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
static int
spwdmodule_exec(PyObject *module)
{
spwdmodulestate *state = get_spwd_state(module);
state->StructSpwdType = PyStructSequence_NewType(&struct_spwd_type_desc);
if (state->StructSpwdType == NULL) {
return -1;
}
if (PyModule_AddType(module, state->StructSpwdType) < 0) {
return -1;
}
return 0;
}
static PyModuleDef_Slot spwdmodule_slots[] = {
{Py_mod_exec, spwdmodule_exec},
{0, NULL}
};
static int spwdmodule_traverse(PyObject *m, visitproc visit, void *arg) {
Py_VISIT(get_spwd_state(m)->StructSpwdType);
return 0;
}
static int spwdmodule_clear(PyObject *m) {
Py_CLEAR(get_spwd_state(m)->StructSpwdType);
return 0;
}
static void spwdmodule_free(void *m) {
spwdmodule_clear((PyObject *)m);
}
static struct PyModuleDef spwdmodule = { static struct PyModuleDef spwdmodule = {
PyModuleDef_HEAD_INIT, PyModuleDef_HEAD_INIT,
"spwd", .m_name = "spwd",
spwd__doc__, .m_doc = spwd__doc__,
-1, .m_size = sizeof(spwdmodulestate),
spwd_methods, .m_methods = spwd_methods,
NULL, .m_slots = spwdmodule_slots,
NULL, .m_traverse = spwdmodule_traverse,
NULL, .m_clear = spwdmodule_clear,
NULL .m_free = spwdmodule_free,
}; };
PyMODINIT_FUNC PyMODINIT_FUNC
PyInit_spwd(void) PyInit_spwd(void)
{ {
PyObject *m; return PyModuleDef_Init(&spwdmodule);
m=PyModule_Create(&spwdmodule);
if (m == NULL)
return NULL;
if (!initialized) {
if (PyStructSequence_InitType2(&StructSpwdType,
&struct_spwd_type_desc) < 0)
return NULL;
}
Py_INCREF((PyObject *) &StructSpwdType);
PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType);
initialized = 1;
return m;
} }