summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDino Viehland <dinoviehland@gmail.com>2019-09-10 11:01:20 (GMT)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2019-09-10 11:01:20 (GMT)
commit5a7d2e11aaea2dd32878dc5c6b1aae8caf56cb44 (patch)
treebcd95470db543aa444c7ad8c855372b2eef10eb8
parent537877d85d1c27d2c2f5189e39da64a7a0c413d3 (diff)
downloadcpython-5a7d2e11aaea2dd32878dc5c6b1aae8caf56cb44.zip
cpython-5a7d2e11aaea2dd32878dc5c6b1aae8caf56cb44.tar.gz
cpython-5a7d2e11aaea2dd32878dc5c6b1aae8caf56cb44.tar.bz2
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
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-46-05.bpo-38069.cn8XLv.rst1
-rw-r--r--Modules/_posixsubprocess.c66
2 files changed, 59 insertions, 8 deletions
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-46-05.bpo-38069.cn8XLv.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-46-05.bpo-38069.cn8XLv.rst
new file mode 100644
index 0000000..6bfe7a7
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-46-05.bpo-38069.cn8XLv.rst
@@ -0,0 +1 @@
+Make _posixsubprocess PEP-384 compatible \ No newline at end of file
diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c
index f68d362..cbdeecf 100644
--- a/Modules/_posixsubprocess.c
+++ b/Modules/_posixsubprocess.c
@@ -49,18 +49,28 @@
#define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0)
+typedef struct {
+ PyObject* disable;
+ PyObject* enable;
+ PyObject* isenabled;
+} _posixsubprocessstate;
+
+static struct PyModuleDef _posixsubprocessmodule;
+
+#define _posixsubprocessstate(o) ((_posixsubprocessstate *)PyModule_GetState(o))
+#define _posixsubprocessstate_global _posixsubprocessstate(PyState_FindModule(&_posixsubprocessmodule))
/* If gc was disabled, call gc.enable(). Return 0 on success. */
static int
_enable_gc(int need_to_reenable_gc, PyObject *gc_module)
{
PyObject *result;
- _Py_IDENTIFIER(enable);
PyObject *exctype, *val, *tb;
if (need_to_reenable_gc) {
PyErr_Fetch(&exctype, &val, &tb);
- result = _PyObject_CallMethodIdNoArgs(gc_module, &PyId_enable);
+ result = _PyObject_CallMethodNoArgs(
+ gc_module, _posixsubprocessstate_global->enable);
if (exctype != NULL) {
PyErr_Restore(exctype, val, tb);
}
@@ -602,13 +612,12 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
/* We need to call gc.disable() when we'll be calling preexec_fn */
if (preexec_fn != Py_None) {
PyObject *result;
- _Py_IDENTIFIER(isenabled);
- _Py_IDENTIFIER(disable);
gc_module = PyImport_ImportModule("gc");
if (gc_module == NULL)
return NULL;
- result = _PyObject_CallMethodIdNoArgs(gc_module, &PyId_isenabled);
+ result = _PyObject_CallMethodNoArgs(
+ gc_module, _posixsubprocessstate_global->isenabled);
if (result == NULL) {
Py_DECREF(gc_module);
return NULL;
@@ -619,7 +628,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args)
Py_DECREF(gc_module);
return NULL;
}
- result = _PyObject_CallMethodIdNoArgs(gc_module, &PyId_disable);
+ result = _PyObject_CallMethodNoArgs(
+ gc_module, _posixsubprocessstate_global->disable);
if (result == NULL) {
Py_DECREF(gc_module);
return NULL;
@@ -798,16 +808,56 @@ static PyMethodDef module_methods[] = {
};
+static int _posixsubprocess_traverse(PyObject *m, visitproc visit, void *arg) {
+ Py_VISIT(_posixsubprocessstate(m)->disable);
+ Py_VISIT(_posixsubprocessstate(m)->enable);
+ Py_VISIT(_posixsubprocessstate(m)->isenabled);
+ return 0;
+}
+
+static int _posixsubprocess_clear(PyObject *m) {
+ Py_CLEAR(_posixsubprocessstate(m)->disable);
+ Py_CLEAR(_posixsubprocessstate(m)->enable);
+ Py_CLEAR(_posixsubprocessstate(m)->isenabled);
+ return 0;
+}
+
+static void _posixsubprocess_free(void *m) {
+ _posixsubprocess_clear((PyObject *)m);
+}
+
static struct PyModuleDef _posixsubprocessmodule = {
PyModuleDef_HEAD_INIT,
"_posixsubprocess",
module_doc,
- -1, /* No memory is needed. */
+ sizeof(_posixsubprocessstate),
module_methods,
+ NULL,
+ _posixsubprocess_traverse,
+ _posixsubprocess_clear,
+ _posixsubprocess_free,
};
PyMODINIT_FUNC
PyInit__posixsubprocess(void)
{
- return PyModule_Create(&_posixsubprocessmodule);
+ PyObject* m;
+
+ m = PyState_FindModule(&_posixsubprocessmodule);
+ if (m != NULL) {
+ Py_INCREF(m);
+ return m;
+ }
+
+ m = PyModule_Create(&_posixsubprocessmodule);
+ if (m == NULL) {
+ return NULL;
+ }
+
+ _posixsubprocessstate(m)->disable = PyUnicode_InternFromString("disable");
+ _posixsubprocessstate(m)->enable = PyUnicode_InternFromString("enable");
+ _posixsubprocessstate(m)->isenabled = PyUnicode_InternFromString("isenabled");
+
+ PyState_AddModule(m, &_posixsubprocessmodule);
+ return m;
}