mirror of
https://github.com/python/cpython.git
synced 2025-11-01 02:38:53 +00:00
bpo-39413: Implement os.unsetenv() on Windows (GH-18163)
The os.unsetenv() function is now also available on Windows.
This commit is contained in:
parent
2d5097663d
commit
161e7b36b1
6 changed files with 160 additions and 59 deletions
|
|
@ -10082,6 +10082,64 @@ posix_putenv_dict_setitem(PyObject *name, PyObject *value)
|
|||
#endif /* PY_PUTENV_DICT */
|
||||
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
static PyObject*
|
||||
win32_putenv(PyObject *name, PyObject *value)
|
||||
{
|
||||
/* Search from index 1 because on Windows starting '=' is allowed for
|
||||
defining hidden environment variables. */
|
||||
if (PyUnicode_GET_LENGTH(name) == 0 ||
|
||||
PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
|
||||
return NULL;
|
||||
}
|
||||
PyObject *unicode;
|
||||
if (value != NULL) {
|
||||
unicode = PyUnicode_FromFormat("%U=%U", name, value);
|
||||
}
|
||||
else {
|
||||
unicode = PyUnicode_FromFormat("%U=", name);
|
||||
}
|
||||
if (unicode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_ssize_t size;
|
||||
/* PyUnicode_AsWideCharString() rejects embedded null characters */
|
||||
wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
|
||||
Py_DECREF(unicode);
|
||||
|
||||
if (env == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (size > _MAX_ENV) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"the environment variable is longer than %u characters",
|
||||
_MAX_ENV);
|
||||
PyMem_Free(env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* _wputenv() and SetEnvironmentVariableW() update the environment in the
|
||||
Process Environment Block (PEB). _wputenv() also updates CRT 'environ'
|
||||
and '_wenviron' variables, whereas SetEnvironmentVariableW() does not.
|
||||
|
||||
Prefer _wputenv() to be compatible with C libraries using CRT
|
||||
variables and CRT functions using these variables (ex: getenv()). */
|
||||
int err = _wputenv(env);
|
||||
PyMem_Free(env);
|
||||
|
||||
if (err) {
|
||||
posix_error();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
/*[clinic input]
|
||||
os.putenv
|
||||
|
|
@ -10097,47 +10155,7 @@ static PyObject *
|
|||
os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
|
||||
/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
|
||||
{
|
||||
const wchar_t *env;
|
||||
Py_ssize_t size;
|
||||
|
||||
/* Search from index 1 because on Windows starting '=' is allowed for
|
||||
defining hidden environment variables. */
|
||||
if (PyUnicode_GET_LENGTH(name) == 0 ||
|
||||
PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "illegal environment variable name");
|
||||
return NULL;
|
||||
}
|
||||
PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
|
||||
if (unicode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
env = PyUnicode_AsUnicodeAndSize(unicode, &size);
|
||||
if (env == NULL)
|
||||
goto error;
|
||||
if (size > _MAX_ENV) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"the environment variable is longer than %u characters",
|
||||
_MAX_ENV);
|
||||
goto error;
|
||||
}
|
||||
if (wcslen(env) != (size_t)size) {
|
||||
PyErr_SetString(PyExc_ValueError, "embedded null character");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (_wputenv(env)) {
|
||||
posix_error();
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(unicode);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
|
||||
error:
|
||||
Py_DECREF(unicode);
|
||||
return NULL;
|
||||
return win32_putenv(name, value);
|
||||
}
|
||||
/* repeat !defined(MS_WINDOWS) to workaround an Argument Clinic issue */
|
||||
#elif (defined(HAVE_SETENV) || defined(HAVE_PUTENV)) && !defined(MS_WINDOWS)
|
||||
|
|
@ -10186,7 +10204,23 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
|
|||
#endif /* defined(HAVE_SETENV) || defined(HAVE_PUTENV) */
|
||||
|
||||
|
||||
#ifdef HAVE_UNSETENV
|
||||
#ifdef MS_WINDOWS
|
||||
/*[clinic input]
|
||||
os.unsetenv
|
||||
name: unicode
|
||||
/
|
||||
|
||||
Delete an environment variable.
|
||||
[clinic start generated code]*/
|
||||
|
||||
static PyObject *
|
||||
os_unsetenv_impl(PyObject *module, PyObject *name)
|
||||
/*[clinic end generated code: output=54c4137ab1834f02 input=4d6a1747cc526d2f]*/
|
||||
{
|
||||
return win32_putenv(name, NULL);
|
||||
}
|
||||
/* repeat !defined(MS_WINDOWS) to workaround an Argument Clinic issue */
|
||||
#elif defined(HAVE_UNSETENV) && !defined(MS_WINDOWS)
|
||||
/*[clinic input]
|
||||
os.unsetenv
|
||||
name: FSConverter
|
||||
|
|
@ -10199,16 +10233,13 @@ static PyObject *
|
|||
os_unsetenv_impl(PyObject *module, PyObject *name)
|
||||
/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
|
||||
{
|
||||
#ifndef HAVE_BROKEN_UNSETENV
|
||||
int err;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_BROKEN_UNSETENV
|
||||
unsetenv(PyBytes_AS_STRING(name));
|
||||
#else
|
||||
err = unsetenv(PyBytes_AS_STRING(name));
|
||||
if (err)
|
||||
int err = unsetenv(PyBytes_AS_STRING(name));
|
||||
if (err) {
|
||||
return posix_error();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PY_PUTENV_DICT
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue