bpo-1635741: Port _posixsubprocess module to multiphase init (GH-23406) · python/cpython@035deee
@@ -85,19 +85,17 @@ get_posixsubprocess_state(PyObject *module)
8585return (_posixsubprocessstate *)state;
8686}
878788-#define _posixsubprocessstate_global get_posixsubprocess_state(PyState_FindModule(&_posixsubprocessmodule))
89-9088/* If gc was disabled, call gc.enable(). Ignore errors. */
9189static void
92-_enable_gc(int need_to_reenable_gc, PyObject *gc_module)
90+_enable_gc(int need_to_reenable_gc, PyObject *gc_module, _posixsubprocessstate *state)
9391{
9492PyObject *result;
9593PyObject *exctype, *val, *tb;
96949795if (need_to_reenable_gc) {
9896PyErr_Fetch(&exctype, &val, &tb);
9997result = PyObject_CallMethodNoArgs(
100-gc_module, _posixsubprocessstate_global->enable);
98+gc_module, state->enable);
10199if (result == NULL) {
102100/* We might have created a child process at this point, we
103101 * we have no good way to handle a failure to reenable GC
@@ -758,7 +756,7 @@ do_fork_exec(char *const exec_array[],
758756759757760758static PyObject *
761-subprocess_fork_exec(PyObject* self, PyObject *args)
759+subprocess_fork_exec(PyObject *module, PyObject *args)
762760{
763761PyObject *gc_module = NULL;
764762PyObject *executable_list, *py_fds_to_keep;
@@ -782,6 +780,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
782780Py_ssize_t arg_num, num_groups = 0;
783781int need_after_fork = 0;
784782int saved_errno = 0;
783+_posixsubprocessstate *state = get_posixsubprocess_state(module);
785784786785if (!PyArg_ParseTuple(
787786args, "OOpO!OOiiiiiiiiiiOOOiO:fork_exec",
@@ -827,7 +826,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
827826if (gc_module == NULL)
828827return NULL;
829828result = PyObject_CallMethodNoArgs(
830-gc_module, _posixsubprocessstate_global->isenabled);
829+gc_module, state->isenabled);
831830if (result == NULL) {
832831Py_DECREF(gc_module);
833832return NULL;
@@ -839,7 +838,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
839838return NULL;
840839 }
841840result = PyObject_CallMethodNoArgs(
842-gc_module, _posixsubprocessstate_global->disable);
841+gc_module, state->disable);
843842if (result == NULL) {
844843Py_DECREF(gc_module);
845844return NULL;
@@ -1073,7 +1072,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
10731072if (exec_array)
10741073_Py_FreeCharPArray(exec_array);
107510741076-_enable_gc(need_to_reenable_gc, gc_module);
1075+_enable_gc(need_to_reenable_gc, gc_module, state);
10771076Py_XDECREF(gc_module);
1078107710791078return pid == -1 ? NULL : PyLong_FromPid(pid);
@@ -1113,12 +1112,38 @@ Raises: Only on an error in the parent process.\n\
11131112PyDoc_STRVAR(module_doc,
11141113"A POSIX helper for the subprocess module.");
111511141115+static int
1116+_posixsubprocess_exec(PyObject *module)
1117+{
1118+_posixsubprocessstate *state = get_posixsubprocess_state(module);
1119+1120+state->disable = PyUnicode_InternFromString("disable");
1121+if (state->disable == NULL) {
1122+return -1;
1123+ }
1124+1125+state->enable = PyUnicode_InternFromString("enable");
1126+if (state->enable == NULL) {
1127+return -1;
1128+ }
1129+1130+state->isenabled = PyUnicode_InternFromString("isenabled");
1131+if (state->isenabled == NULL) {
1132+return -1;
1133+ }
1134+1135+return 0;
1136+}
1116113711171138static PyMethodDef module_methods[] = {
11181139 {"fork_exec", subprocess_fork_exec, METH_VARARGS, subprocess_fork_exec_doc},
11191140 {NULL, NULL} /* sentinel */
11201141};
112111421143+static PyModuleDef_Slot _posixsubprocess_slots[] = {
1144+ {Py_mod_exec, _posixsubprocess_exec},
1145+ {0, NULL}
1146+};
1122114711231148static int _posixsubprocess_traverse(PyObject *m, visitproc visit, void *arg) {
11241149Py_VISIT(get_posixsubprocess_state(m)->disable);
@@ -1140,36 +1165,18 @@ static void _posixsubprocess_free(void *m) {
1140116511411166static struct PyModuleDef _posixsubprocessmodule = {
11421167PyModuleDef_HEAD_INIT,
1143-"_posixsubprocess",
1144-module_doc,
1145-sizeof(_posixsubprocessstate),
1146-module_methods,
1147-NULL,
1148-_posixsubprocess_traverse,
1149-_posixsubprocess_clear,
1150-_posixsubprocess_free,
1168+.m_name = "_posixsubprocess",
1169+.m_doc = module_doc,
1170+.m_size = sizeof(_posixsubprocessstate),
1171+.m_methods = module_methods,
1172+.m_slots = _posixsubprocess_slots,
1173+.m_traverse = _posixsubprocess_traverse,
1174+.m_clear = _posixsubprocess_clear,
1175+.m_free = _posixsubprocess_free,
11511176};
1152117711531178PyMODINIT_FUNC
11541179PyInit__posixsubprocess(void)
11551180{
1156-PyObject* m;
1157-1158-m = PyState_FindModule(&_posixsubprocessmodule);
1159-if (m != NULL) {
1160-Py_INCREF(m);
1161-return m;
1162- }
1163-1164-m = PyModule_Create(&_posixsubprocessmodule);
1165-if (m == NULL) {
1166-return NULL;
1167- }
1168-1169-get_posixsubprocess_state(m)->disable = PyUnicode_InternFromString("disable");
1170-get_posixsubprocess_state(m)->enable = PyUnicode_InternFromString("enable");
1171-get_posixsubprocess_state(m)->isenabled = PyUnicode_InternFromString("isenabled");
1172-1173-PyState_AddModule(m, &_posixsubprocessmodule);
1174-return m;
1181+return PyModuleDef_Init(&_posixsubprocessmodule);
11751182}