mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
bpo-39413: Implement os.unsetenv() on Windows (GH-18104)
The os.unsetenv() function is now also available on Windows. It is implemented with SetEnvironmentVariableW(name, NULL).
This commit is contained in:
parent
59e2d26b25
commit
56cd3710a1
6 changed files with 92 additions and 12 deletions
|
@ -645,6 +645,9 @@ process and user.
|
||||||
|
|
||||||
.. availability:: most flavors of Unix, Windows.
|
.. availability:: most flavors of Unix, Windows.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.9
|
||||||
|
The function is now also available on Windows.
|
||||||
|
|
||||||
|
|
||||||
.. _os-newstreams:
|
.. _os-newstreams:
|
||||||
|
|
||||||
|
|
|
@ -216,6 +216,9 @@ Exposed the Linux-specific :func:`os.pidfd_open` (:issue:`38692`) and
|
||||||
:data:`os.P_PIDFD` (:issue:`38713`) for process management with file
|
:data:`os.P_PIDFD` (:issue:`38713`) for process management with file
|
||||||
descriptors.
|
descriptors.
|
||||||
|
|
||||||
|
The :func:`os.unsetenv` function is now also available on Windows.
|
||||||
|
(Contributed by Victor Stinner in :issue:`39413`.)
|
||||||
|
|
||||||
poplib
|
poplib
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -956,11 +956,6 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol):
|
||||||
# On OS X < 10.6, unsetenv() doesn't return a value (bpo-13415).
|
# On OS X < 10.6, unsetenv() doesn't return a value (bpo-13415).
|
||||||
@support.requires_mac_ver(10, 6)
|
@support.requires_mac_ver(10, 6)
|
||||||
def test_unset_error(self):
|
def test_unset_error(self):
|
||||||
if sys.platform == "win32":
|
|
||||||
# an environment variable is limited to 32,767 characters
|
|
||||||
key = 'x' * 50000
|
|
||||||
self.assertRaises(ValueError, os.environ.__delitem__, key)
|
|
||||||
else:
|
|
||||||
# "=" is not allowed in a variable name
|
# "=" is not allowed in a variable name
|
||||||
key = 'key='
|
key = 'key='
|
||||||
self.assertRaises(OSError, os.environ.__delitem__, key)
|
self.assertRaises(OSError, os.environ.__delitem__, key)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
The :func:`os.unsetenv` function is now also available on Windows.
|
42
Modules/clinic/posixmodule.c.h
generated
42
Modules/clinic/posixmodule.c.h
generated
|
@ -6125,7 +6125,43 @@ exit:
|
||||||
|
|
||||||
#endif /* defined(HAVE_PUTENV) && !defined(MS_WINDOWS) */
|
#endif /* defined(HAVE_PUTENV) && !defined(MS_WINDOWS) */
|
||||||
|
|
||||||
#if defined(HAVE_UNSETENV)
|
#if defined(MS_WINDOWS)
|
||||||
|
|
||||||
|
PyDoc_STRVAR(os_unsetenv__doc__,
|
||||||
|
"unsetenv($module, name, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Delete an environment variable.");
|
||||||
|
|
||||||
|
#define OS_UNSETENV_METHODDEF \
|
||||||
|
{"unsetenv", (PyCFunction)os_unsetenv, METH_O, os_unsetenv__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
os_unsetenv_impl(PyObject *module, PyObject *name);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
os_unsetenv(PyObject *module, PyObject *arg)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
PyObject *name;
|
||||||
|
|
||||||
|
if (!PyUnicode_Check(arg)) {
|
||||||
|
_PyArg_BadArgument("unsetenv", "argument", "str", arg);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (PyUnicode_READY(arg) == -1) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
name = arg;
|
||||||
|
return_value = os_unsetenv_impl(module, name);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(MS_WINDOWS) */
|
||||||
|
|
||||||
|
#if (defined(HAVE_UNSETENV) && !defined(MS_WINDOWS))
|
||||||
|
|
||||||
PyDoc_STRVAR(os_unsetenv__doc__,
|
PyDoc_STRVAR(os_unsetenv__doc__,
|
||||||
"unsetenv($module, name, /)\n"
|
"unsetenv($module, name, /)\n"
|
||||||
|
@ -6157,7 +6193,7 @@ exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined(HAVE_UNSETENV) */
|
#endif /* (defined(HAVE_UNSETENV) && !defined(MS_WINDOWS)) */
|
||||||
|
|
||||||
PyDoc_STRVAR(os_strerror__doc__,
|
PyDoc_STRVAR(os_strerror__doc__,
|
||||||
"strerror($module, code, /)\n"
|
"strerror($module, code, /)\n"
|
||||||
|
@ -8773,4 +8809,4 @@ exit:
|
||||||
#ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF
|
#ifndef OS__REMOVE_DLL_DIRECTORY_METHODDEF
|
||||||
#define OS__REMOVE_DLL_DIRECTORY_METHODDEF
|
#define OS__REMOVE_DLL_DIRECTORY_METHODDEF
|
||||||
#endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */
|
#endif /* !defined(OS__REMOVE_DLL_DIRECTORY_METHODDEF) */
|
||||||
/*[clinic end generated code: output=51ba5b9536420cea input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=6e739a2715712e88 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -10163,7 +10163,49 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
|
||||||
#endif /* HAVE_PUTENV */
|
#endif /* 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]*/
|
||||||
|
{
|
||||||
|
/* PyUnicode_AsWideCharString() rejects embedded null characters */
|
||||||
|
wchar_t *name_str = PyUnicode_AsWideCharString(name, NULL);
|
||||||
|
if (name_str == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ok = SetEnvironmentVariableW(name_str, NULL);
|
||||||
|
PyMem_Free(name_str);
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
return PyErr_SetFromWindowsErr(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the key from posix_putenv_garbage;
|
||||||
|
* 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)) {
|
||||||
|
/* really not much we can do; just leak */
|
||||||
|
if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
/* repeat !defined(MS_WINDOWS) to workaround an Argument Clinic issue */
|
||||||
|
#elif defined(HAVE_UNSETENV) && !defined(MS_WINDOWS)
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
os.unsetenv
|
os.unsetenv
|
||||||
name: FSConverter
|
name: FSConverter
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue