[Python-checkins] bpo-38069: Convert _posixsubprocess to PEP-384 (GH-15780)

Miss Islington (bot) webhook-mailer at python.org
Tue Sep 10 07:01:24 EDT 2019


https://github.com/python/cpython/commit/5a7d2e11aaea2dd32878dc5c6b1aae8caf56cb44
commit: 5a7d2e11aaea2dd32878dc5c6b1aae8caf56cb44
branch: master
author: Dino Viehland <dinoviehland at gmail.com>
committer: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
date: 2019-09-10T04:01:20-07:00
summary:

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

files:
A Misc/NEWS.d/next/Core and Builtins/2019-09-09-14-46-05.bpo-38069.cn8XLv.rst
M Modules/_posixsubprocess.c

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 000000000000..6bfe7a744f6e
--- /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 f68d362acc04..cbdeecfda1c2 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;
 }



More information about the Python-checkins mailing list