[Python-checkins] bpo-39406: Add PY_PUTENV_DICT macro to posixmodule.c (GH-18106)

Victor Stinner webhook-mailer at python.org
Tue Jan 21 13:25:47 EST 2020


https://github.com/python/cpython/commit/623ed6171eae35af7fd2e804dfd9c832c05c5d48
commit: 623ed6171eae35af7fd2e804dfd9c832c05c5d48
branch: master
author: Victor Stinner <vstinner at python.org>
committer: GitHub <noreply at github.com>
date: 2020-01-21T19:25:32+01:00
summary:

bpo-39406: Add PY_PUTENV_DICT macro to posixmodule.c (GH-18106)

Rename posix_putenv_garbage to putenv_dict.

files:
M Modules/posixmodule.c

diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index d2047d9c2ac1f..5a0c8a311a790 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -819,9 +819,19 @@ dir_fd_converter(PyObject *o, void *p)
     }
 }
 
+#ifdef HAVE_PUTENV
+#  define PY_PUTENV_DICT
+#endif
+
 typedef struct {
     PyObject *billion;
-    PyObject *posix_putenv_garbage;
+#ifdef PY_PUTENV_DICT
+    /* putenv() and _wputenv() requires that the caller manages the environment
+       variable memory. Use a Python dictionary for that: name => env, where
+       env is a string like "name=value". On Windows, dict keys and values are
+       Unicode strings. On Unix, they are bytes strings. */
+    PyObject *putenv_dict;
+#endif
     PyObject *DirEntryType;
     PyObject *ScandirIteratorType;
 #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -2105,7 +2115,9 @@ static int
 _posix_clear(PyObject *module)
 {
     Py_CLEAR(_posixstate(module)->billion);
-    Py_CLEAR(_posixstate(module)->posix_putenv_garbage);
+#ifdef PY_PUTENV_DICT
+    Py_CLEAR(_posixstate(module)->putenv_dict);
+#endif
     Py_CLEAR(_posixstate(module)->DirEntryType);
     Py_CLEAR(_posixstate(module)->ScandirIteratorType);
 #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -2130,7 +2142,9 @@ static int
 _posix_traverse(PyObject *module, visitproc visit, void *arg)
 {
     Py_VISIT(_posixstate(module)->billion);
-    Py_VISIT(_posixstate(module)->posix_putenv_garbage);
+#ifdef PY_PUTENV_DICT
+    Py_VISIT(_posixstate(module)->putenv_dict);
+#endif
     Py_VISIT(_posixstate(module)->DirEntryType);
     Py_VISIT(_posixstate(module)->ScandirIteratorType);
 #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
@@ -10047,23 +10061,26 @@ os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
 }
 #endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
 
-#ifdef HAVE_PUTENV
 
+#ifdef PY_PUTENV_DICT
 static void
-posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
+posix_putenv_dict_setitem(PyObject *name, PyObject *value)
 {
-    /* Install the first arg and newstr in posix_putenv_garbage;
+    /* Install the first arg and newstr in putenv_dict;
      * this will cause previous value to be collected.  This has to
      * happen after the real putenv() call because the old value
      * was still accessible until then. */
-    if (PyDict_SetItem(_posixstate_global->posix_putenv_garbage, name, value))
+    if (PyDict_SetItem(_posixstate_global->putenv_dict, name, value))
         /* really not much we can do; just leak */
         PyErr_Clear();
     else
         Py_DECREF(value);
 }
+#endif  /* PY_PUTENV_DICT */
 
 
+#ifdef HAVE_PUTENV
+
 #ifdef MS_WINDOWS
 /*[clinic input]
 os.putenv
@@ -10114,7 +10131,7 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
         goto error;
     }
 
-    posix_putenv_garbage_setitem(name, unicode);
+    posix_putenv_dict_setitem(name, unicode);
     Py_RETURN_NONE;
 
 error:
@@ -10156,7 +10173,7 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
         return posix_error();
     }
 
-    posix_putenv_garbage_setitem(name, bytes);
+    posix_putenv_dict_setitem(name, bytes);
     Py_RETURN_NONE;
 }
 #endif /* MS_WINDOWS */
@@ -10189,18 +10206,20 @@ os_unsetenv_impl(PyObject *module, PyObject *name)
         return PyErr_SetFromWindowsErr(0);
     }
 
-    /* Remove the key from posix_putenv_garbage;
+#ifdef PY_PUTENV_DICT
+    /* Remove the key from putenv_dict;
      * this will cause it to be collected.  This has to
      * happen after the real unsetenv() call because the
      * old value was still accessible until then.
      */
-    if (PyDict_DelItem(_posixstate(module)->posix_putenv_garbage, name)) {
+    if (PyDict_DelItem(_posixstate(module)->putenv_dict, name)) {
         /* really not much we can do; just leak */
         if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
             return NULL;
         }
         PyErr_Clear();
     }
+#endif
 
     Py_RETURN_NONE;
 }
@@ -10230,18 +10249,21 @@ os_unsetenv_impl(PyObject *module, PyObject *name)
         return posix_error();
 #endif
 
-    /* Remove the key from posix_putenv_garbage;
+#ifdef PY_PUTENV_DICT
+    /* Remove the key from putenv_dict;
      * this will cause it to be collected.  This has to
      * happen after the real unsetenv() call because the
      * old value was still accessible until then.
      */
-    if (PyDict_DelItem(_posixstate(module)->posix_putenv_garbage, name)) {
+    if (PyDict_DelItem(_posixstate(module)->putenv_dict, name)) {
         /* really not much we can do; just leak */
         if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
             return NULL;
         }
         PyErr_Clear();
     }
+#endif
+
     Py_RETURN_NONE;
 }
 #endif /* HAVE_UNSETENV */
@@ -14538,10 +14560,10 @@ INITFUNC(void)
     Py_INCREF(PyExc_OSError);
     PyModule_AddObject(m, "error", PyExc_OSError);
 
-#ifdef HAVE_PUTENV
+#ifdef PY_PUTENV_DICT
     /* Save putenv() parameters as values here, so we can collect them when they
      * get re-set with another call for the same key. */
-    _posixstate(m)->posix_putenv_garbage = PyDict_New();
+    _posixstate(m)->putenv_dict = PyDict_New();
 #endif
 
 #if defined(HAVE_WAITID) && !defined(__APPLE__)



More information about the Python-checkins mailing list