| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -10079,53 +10079,31 @@ posix_putenv_dict_setitem(PyObject *name, PyObject *value) | |
| #endif /* PY_PUTENV_DICT */ | ||
|
|
||
|
|
||
| #ifdef HAVE_PUTENV | ||
|
|
||
| #ifdef MS_WINDOWS | ||
| /*[clinic input] | ||
| os.putenv | ||
|
|
||
| name: unicode | ||
| value: unicode | ||
| / | ||
|
|
||
| Change or add an environment variable. | ||
| [clinic start generated code]*/ | ||
|
|
||
| static PyObject * | ||
| os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) | ||
| /*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/ | ||
| static PyObject* | ||
| py_win_putenv(PyObject *name, PyObject *value) | ||
| { | ||
| 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) | ||
| const wchar_t *env; | ||
| Py_ssize_t size; | ||
| /* PyUnicode_AsWideCharString() rejects embedded null characters */ | ||
| env = PyUnicode_AsWideCharString(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; | ||
| } | ||
|
|
||
| /* Use _wputenv() rather than SetEnvironmentVariableW(): _wputenv() | ||
|
Comment thread
Outdated
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThe search for "=" (line 10102) should begin at index 0, not index 1. Windows allows variable names that begin with 0, but ucrt does not allow it. For example: >>> os.putenv('spam=', 'eggs')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: illegal environment variable name
>>> os.putenv('=spam', 'eggs')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI noticed this surprising difference and I'm trying to understand what should be the correct behavior...
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityDoes it work with '=C'?
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityPython initializes nt.environ from C _wenviron, so it follows the long-standing convention of MSVC to exclude hidden variables that begin with "=" and to disallow setting them. We still set them for per-drive working directories (e.g. "=Z:"), but we set them in the process environment only, with SetEnvironmentVariableW. For example, see win32_wchdir in this module. The drive variables are supposed to be a hidden implementation detail. CMD's set doesn't show them, except due to a parsing bug if we run set "" or set ".
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIf you want to allow setting them, then Python should initialize nt.environ from WINAPI GetEnvironmentStringsW instead of _wenviron (or at least also from GetEnvironmentStringsW , just for the hidden variables). Then if a name begins with "=", call SetEnvironmentVariableW instead of _wputenv.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWhat about os.unsetenv("key=value")?
Because in "key==value" what is a key and what is a value? key=="key" and value=="=value" or key=="key=" and value=="value"?
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityWindows is so weird. The official documentation says:
I tested: I can set a variable with name "zlong=" (the name contains "="). It is shown by the set command for example: >>> import os
>>> os.putenv("zlong=", "1")
>>> os.putenv("zlon=g", "2")
>>> os.system("set")
(...)
zlon=g=2
zlong==1
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityThe posix_putenv_dict_setitem call below is unnecessary with _wputenv. It copies the string before adding it to _wenviron, i.e. it does not comply with POSIX putenv.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI checked back to even Python 2.7 w/ msvcr90.dll, and even that old version of the CRT copies the string that's passed to putenv (via calls to _calloc_crt and strcpy_s), which I verified by noting the result from _calloc_crt and cross-checking with the address returned by getenv. The CRT didn't used to copy the string back in the 1990s, but that's ancient history.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Fixed in commit 0852c7d.
Sorry, something went wrong.
All reactions
|
||
| updates the CRT, whereas SetEnvironmentVariableW() does not. */ | ||
| if (_wputenv(env)) { | ||
| posix_error(); | ||
| goto error; | ||
| Expand All | @@ -10138,7 +10116,37 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) | |
| Py_DECREF(unicode); | ||
| return NULL; | ||
| } | ||
| #else /* MS_WINDOWS */ | ||
| #endif | ||
|
|
||
|
|
||
| #ifdef MS_WINDOWS | ||
| /*[clinic input] | ||
| os.putenv | ||
|
|
||
| name: unicode | ||
| value: unicode | ||
| / | ||
|
|
||
| Change or add an environment variable. | ||
| [clinic start generated code]*/ | ||
|
|
||
| static PyObject * | ||
| os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) | ||
| /*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/ | ||
| { | ||
| /* 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) | ||
|
Comment thread
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityAgain, this search should start at index 0, so that it consistently raises ValueError, instead of OSError if a name begins with "=".
Sorry, something went wrong.
All reactions
|
||
| { | ||
| PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); | ||
| return NULL; | ||
| } | ||
|
|
||
| return py_win_putenv(name, value); | ||
| } | ||
| /* repeat !defined(MS_WINDOWS) to workaround an Argument Clinic issue */ | ||
| #elif defined(HAVE_PUTENV) && !defined(MS_WINDOWS) | ||
| /*[clinic input] | ||
| os.putenv | ||
|
|
||
| Expand Down Expand Up | @@ -10176,8 +10184,7 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) | |
| posix_putenv_dict_setitem(name, bytes); | ||
| Py_RETURN_NONE; | ||
| } | ||
| #endif /* MS_WINDOWS */ | ||
| #endif /* HAVE_PUTENV */ | ||
| #endif /* defined(HAVE_PUTENV) && !defined(MS_WINDOWS) */ | ||
|
|
||
|
|
||
| #ifdef MS_WINDOWS | ||
| Expand All | @@ -10193,35 +10200,16 @@ 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) { | ||
| PyObject *empty = PyUnicode_New(0, 0); | ||
| if (empty == NULL) { | ||
| return NULL; | ||
| } | ||
|
|
||
| BOOL ok = SetEnvironmentVariableW(name_str, NULL); | ||
| PyMem_Free(name_str); | ||
|
|
||
| if (!ok) { | ||
| return PyErr_SetFromWindowsErr(0); | ||
| } | ||
| /* _wputenv("name=") removes the environment variable "name" */ | ||
| PyObject *res = py_win_putenv(name, empty); | ||
| Py_DECREF(empty); | ||
|
|
||
| #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)->putenv_dict, name)) { | ||
| /* really not much we can do; just leak */ | ||
| if (!PyErr_ExceptionMatches(PyExc_KeyError)) { | ||
| return NULL; | ||
| } | ||
| PyErr_Clear(); | ||
| } | ||
| #endif | ||
|
|
||
| Py_RETURN_NONE; | ||
| return res; | ||
| } | ||
| /* repeat !defined(MS_WINDOWS) to workaround an Argument Clinic issue */ | ||
| #elif defined(HAVE_UNSETENV) && !defined(MS_WINDOWS) | ||
| Expand Down | ||
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityIs py_win_ the naming convention from now on -- as opposed to win32_?
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.