Skip to content

Commit bf9d70a

Browse files
authored
bpo-1635741: Port spwd to multiphase initialization (GH-23390)
Signed-off-by: Christian Heimes <christian@python.org>
1 parent 3094dd5 commit bf9d70a

File tree

2 files changed

+58
-27
lines changed

2 files changed

+58
-27
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Port :mod:`spwd` extension module to multiphase initialization (:pep:`489`)

Modules/spwdmodule.c

+57-27
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,19 @@ static PyStructSequence_Desc struct_spwd_type_desc = {
5959
9,
6060
};
6161

62-
static int initialized;
63-
static PyTypeObject StructSpwdType;
62+
typedef struct {
63+
PyTypeObject *StructSpwdType;
64+
} spwdmodulestate;
6465

66+
static inline spwdmodulestate*
67+
get_spwd_state(PyObject *module)
68+
{
69+
void *state = PyModule_GetState(module);
70+
assert(state != NULL);
71+
return (spwdmodulestate *)state;
72+
}
73+
74+
static struct PyModuleDef spwdmodule;
6575

6676
static void
6777
sets(PyObject *v, int i, const char* val)
@@ -75,10 +85,10 @@ sets(PyObject *v, int i, const char* val)
7585
}
7686
}
7787

78-
static PyObject *mkspent(struct spwd *p)
88+
static PyObject *mkspent(PyObject *module, struct spwd *p)
7989
{
8090
int setIndex = 0;
81-
PyObject *v = PyStructSequence_New(&StructSpwdType);
91+
PyObject *v = PyStructSequence_New(get_spwd_state(module)->StructSpwdType);
8292
if (v == NULL)
8393
return NULL;
8494

@@ -144,7 +154,7 @@ spwd_getspnam_impl(PyObject *module, PyObject *arg)
144154
PyErr_SetString(PyExc_KeyError, "getspnam(): name not found");
145155
goto out;
146156
}
147-
retval = mkspent(p);
157+
retval = mkspent(module, p);
148158
out:
149159
Py_DECREF(bytes);
150160
return retval;
@@ -172,7 +182,7 @@ spwd_getspall_impl(PyObject *module)
172182
return NULL;
173183
setspent();
174184
while ((p = getspent()) != NULL) {
175-
PyObject *v = mkspent(p);
185+
PyObject *v = mkspent(module, p);
176186
if (v == NULL || PyList_Append(d, v) != 0) {
177187
Py_XDECREF(v);
178188
Py_DECREF(d);
@@ -197,34 +207,54 @@ static PyMethodDef spwd_methods[] = {
197207
{NULL, NULL} /* sentinel */
198208
};
199209

210+
static int
211+
spwdmodule_exec(PyObject *module)
212+
{
213+
spwdmodulestate *state = get_spwd_state(module);
214+
215+
state->StructSpwdType = PyStructSequence_NewType(&struct_spwd_type_desc);
216+
if (state->StructSpwdType == NULL) {
217+
return -1;
218+
}
219+
if (PyModule_AddType(module, state->StructSpwdType) < 0) {
220+
return -1;
221+
}
222+
return 0;
223+
}
224+
225+
static PyModuleDef_Slot spwdmodule_slots[] = {
226+
{Py_mod_exec, spwdmodule_exec},
227+
{0, NULL}
228+
};
229+
230+
static int spwdmodule_traverse(PyObject *m, visitproc visit, void *arg) {
231+
Py_VISIT(get_spwd_state(m)->StructSpwdType);
232+
return 0;
233+
}
200234

235+
static int spwdmodule_clear(PyObject *m) {
236+
Py_CLEAR(get_spwd_state(m)->StructSpwdType);
237+
return 0;
238+
}
239+
240+
static void spwdmodule_free(void *m) {
241+
spwdmodule_clear((PyObject *)m);
242+
}
201243

202244
static struct PyModuleDef spwdmodule = {
203245
PyModuleDef_HEAD_INIT,
204-
"spwd",
205-
spwd__doc__,
206-
-1,
207-
spwd_methods,
208-
NULL,
209-
NULL,
210-
NULL,
211-
NULL
246+
.m_name = "spwd",
247+
.m_doc = spwd__doc__,
248+
.m_size = sizeof(spwdmodulestate),
249+
.m_methods = spwd_methods,
250+
.m_slots = spwdmodule_slots,
251+
.m_traverse = spwdmodule_traverse,
252+
.m_clear = spwdmodule_clear,
253+
.m_free = spwdmodule_free,
212254
};
213255

214256
PyMODINIT_FUNC
215257
PyInit_spwd(void)
216258
{
217-
PyObject *m;
218-
m=PyModule_Create(&spwdmodule);
219-
if (m == NULL)
220-
return NULL;
221-
if (!initialized) {
222-
if (PyStructSequence_InitType2(&StructSpwdType,
223-
&struct_spwd_type_desc) < 0)
224-
return NULL;
225-
}
226-
Py_INCREF((PyObject *) &StructSpwdType);
227-
PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType);
228-
initialized = 1;
229-
return m;
259+
return PyModuleDef_Init(&spwdmodule);
230260
}

0 commit comments

Comments
 (0)