Skip to content

Commit 5a7d2e1

Browse files
DinoVmiss-islington
authored andcommitted
bpo-38069: Convert _posixsubprocess to PEP-384 (GH-15780)
Summary: Eliminate uses of `_Py_IDENTIFIER` from `_posixsubprocess`, replacing them with interned strings. Also tries to find an existing version of the module, which will allow subinterpreters. https://bugs.python.org/issue38069
1 parent 537877d commit 5a7d2e1

File tree

2 files changed

+59
-8
lines changed

2 files changed

+59
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make _posixsubprocess PEP-384 compatible

Modules/_posixsubprocess.c

+58-8
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,28 @@
4949

5050
#define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0)
5151

52+
typedef struct {
53+
PyObject* disable;
54+
PyObject* enable;
55+
PyObject* isenabled;
56+
} _posixsubprocessstate;
57+
58+
static struct PyModuleDef _posixsubprocessmodule;
59+
60+
#define _posixsubprocessstate(o) ((_posixsubprocessstate *)PyModule_GetState(o))
61+
#define _posixsubprocessstate_global _posixsubprocessstate(PyState_FindModule(&_posixsubprocessmodule))
5262

5363
/* If gc was disabled, call gc.enable(). Return 0 on success. */
5464
static int
5565
_enable_gc(int need_to_reenable_gc, PyObject *gc_module)
5666
{
5767
PyObject *result;
58-
_Py_IDENTIFIER(enable);
5968
PyObject *exctype, *val, *tb;
6069

6170
if (need_to_reenable_gc) {
6271
PyErr_Fetch(&exctype, &val, &tb);
63-
result = _PyObject_CallMethodIdNoArgs(gc_module, &PyId_enable);
72+
result = _PyObject_CallMethodNoArgs(
73+
gc_module, _posixsubprocessstate_global->enable);
6474
if (exctype != NULL) {
6575
PyErr_Restore(exctype, val, tb);
6676
}
@@ -602,13 +612,12 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
602612
/* We need to call gc.disable() when we'll be calling preexec_fn */
603613
if (preexec_fn != Py_None) {
604614
PyObject *result;
605-
_Py_IDENTIFIER(isenabled);
606-
_Py_IDENTIFIER(disable);
607615

608616
gc_module = PyImport_ImportModule("gc");
609617
if (gc_module == NULL)
610618
return NULL;
611-
result = _PyObject_CallMethodIdNoArgs(gc_module, &PyId_isenabled);
619+
result = _PyObject_CallMethodNoArgs(
620+
gc_module, _posixsubprocessstate_global->isenabled);
612621
if (result == NULL) {
613622
Py_DECREF(gc_module);
614623
return NULL;
@@ -619,7 +628,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
619628
Py_DECREF(gc_module);
620629
return NULL;
621630
}
622-
result = _PyObject_CallMethodIdNoArgs(gc_module, &PyId_disable);
631+
result = _PyObject_CallMethodNoArgs(
632+
gc_module, _posixsubprocessstate_global->disable);
623633
if (result == NULL) {
624634
Py_DECREF(gc_module);
625635
return NULL;
@@ -798,16 +808,56 @@ static PyMethodDef module_methods[] = {
798808
};
799809

800810

811+
static int _posixsubprocess_traverse(PyObject *m, visitproc visit, void *arg) {
812+
Py_VISIT(_posixsubprocessstate(m)->disable);
813+
Py_VISIT(_posixsubprocessstate(m)->enable);
814+
Py_VISIT(_posixsubprocessstate(m)->isenabled);
815+
return 0;
816+
}
817+
818+
static int _posixsubprocess_clear(PyObject *m) {
819+
Py_CLEAR(_posixsubprocessstate(m)->disable);
820+
Py_CLEAR(_posixsubprocessstate(m)->enable);
821+
Py_CLEAR(_posixsubprocessstate(m)->isenabled);
822+
return 0;
823+
}
824+
825+
static void _posixsubprocess_free(void *m) {
826+
_posixsubprocess_clear((PyObject *)m);
827+
}
828+
801829
static struct PyModuleDef _posixsubprocessmodule = {
802830
PyModuleDef_HEAD_INIT,
803831
"_posixsubprocess",
804832
module_doc,
805-
-1, /* No memory is needed. */
833+
sizeof(_posixsubprocessstate),
806834
module_methods,
835+
NULL,
836+
_posixsubprocess_traverse,
837+
_posixsubprocess_clear,
838+
_posixsubprocess_free,
807839
};
808840

809841
PyMODINIT_FUNC
810842
PyInit__posixsubprocess(void)
811843
{
812-
return PyModule_Create(&_posixsubprocessmodule);
844+
PyObject* m;
845+
846+
m = PyState_FindModule(&_posixsubprocessmodule);
847+
if (m != NULL) {
848+
Py_INCREF(m);
849+
return m;
850+
}
851+
852+
m = PyModule_Create(&_posixsubprocessmodule);
853+
if (m == NULL) {
854+
return NULL;
855+
}
856+
857+
_posixsubprocessstate(m)->disable = PyUnicode_InternFromString("disable");
858+
_posixsubprocessstate(m)->enable = PyUnicode_InternFromString("enable");
859+
_posixsubprocessstate(m)->isenabled = PyUnicode_InternFromString("isenabled");
860+
861+
PyState_AddModule(m, &_posixsubprocessmodule);
862+
return m;
813863
}

0 commit comments

Comments
 (0)