bpo-39413: Implement os.unsetenv() on Windows by vstinner · Pull Request #18163 · python/cpython
Consider calling _wputenv_s, which has separate parameters for the name and value. Also, other win32_ functions in this module take C data types. I think it would be simpler to change the clinic definition of os.putenv and os.unsetenv to use Py_UNICODE. This is argument type "u", which is based on PyUnicode_AsUnicodeAndSize and checks for embedded null characters. The code for os_unsetenv_impl would change to calling win32_putenv(name, L""). Here's what this might look like -- off the top my head, so excuse any errors:
static PyObject * win32_putenv(wchar_t *name, wchar_t *value) { size_t name_length = wcslen(name); if (!name_length || wcschr(name, L'=')) { PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); return NULL; } if (name_length >= _MAX_ENV) { PyErr_Format(PyExc_ValueError, "the environment variable name " "is longer than %u characters", _MAX_ENV - 1); return NULL; } if (wcslen(value) >= _MAX_ENV) { PyErr_Format(PyExc_ValueError, "the environment variable value " "is longer than %u characters", _MAX_ENV - 1); return NULL; } /* Both _wputenv_s() and SetEnvironmentVariableW() update the environment in the Process Environment Block (PEB), but _wputenv_s() also updates the CRT environ and _wenviron variables. Use _wputenv_s() in order to be compatible with C libraries that use the CRT variables and the CRT functions that use these variables, such as getenv(). */ errno_t err; _Py_BEGIN_SUPPRESS_IPH err = _wputenv_s(name, value); _Py_END_SUPPRESS_IPH if (err) { posix_error(); return NULL; } Py_RETURN_NONE; }