bpo-1635741: Port _posixsubprocess module to multiphase init (GH-23406) · python/cpython@035deee

@@ -85,19 +85,17 @@ get_posixsubprocess_state(PyObject *module)

8585

return (_posixsubprocessstate *)state;

8686

}

878788-

#define _posixsubprocessstate_global get_posixsubprocess_state(PyState_FindModule(&_posixsubprocessmodule))

89-9088

/* If gc was disabled, call gc.enable(). Ignore errors. */

9189

static 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

{

9492

PyObject *result;

9593

PyObject *exctype, *val, *tb;

96949795

if (need_to_reenable_gc) {

9896

PyErr_Fetch(&exctype, &val, &tb);

9997

result = PyObject_CallMethodNoArgs(

100-

gc_module, _posixsubprocessstate_global->enable);

98+

gc_module, state->enable);

10199

if (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[],

758756759757760758

static PyObject *

761-

subprocess_fork_exec(PyObject* self, PyObject *args)

759+

subprocess_fork_exec(PyObject *module, PyObject *args)

762760

{

763761

PyObject *gc_module = NULL;

764762

PyObject *executable_list, *py_fds_to_keep;

@@ -782,6 +780,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)

782780

Py_ssize_t arg_num, num_groups = 0;

783781

int need_after_fork = 0;

784782

int saved_errno = 0;

783+

_posixsubprocessstate *state = get_posixsubprocess_state(module);

785784786785

if (!PyArg_ParseTuple(

787786

args, "OOpO!OOiiiiiiiiiiOOOiO:fork_exec",

@@ -827,7 +826,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)

827826

if (gc_module == NULL)

828827

return NULL;

829828

result = PyObject_CallMethodNoArgs(

830-

gc_module, _posixsubprocessstate_global->isenabled);

829+

gc_module, state->isenabled);

831830

if (result == NULL) {

832831

Py_DECREF(gc_module);

833832

return NULL;

@@ -839,7 +838,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)

839838

return NULL;

840839

}

841840

result = PyObject_CallMethodNoArgs(

842-

gc_module, _posixsubprocessstate_global->disable);

841+

gc_module, state->disable);

843842

if (result == NULL) {

844843

Py_DECREF(gc_module);

845844

return NULL;

@@ -1073,7 +1072,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args)

10731072

if (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);

10771076

Py_XDECREF(gc_module);

1078107710791078

return pid == -1 ? NULL : PyLong_FromPid(pid);

@@ -1113,12 +1112,38 @@ Raises: Only on an error in the parent process.\n\

11131112

PyDoc_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+

}

1116113711171138

static 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+

};

1122114711231148

static int _posixsubprocess_traverse(PyObject *m, visitproc visit, void *arg) {

11241149

Py_VISIT(get_posixsubprocess_state(m)->disable);

@@ -1140,36 +1165,18 @@ static void _posixsubprocess_free(void *m) {

1140116511411166

static struct PyModuleDef _posixsubprocessmodule = {

11421167

PyModuleDef_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

};

1152117711531178

PyMODINIT_FUNC

11541179

PyInit__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

}