[WIP] bpo-39413: os.unsetenv() uses _wputenv() on Windows#18115
[WIP] bpo-39413: os.unsetenv() uses _wputenv() on Windows#18115vstinner wants to merge 1 commit into
Conversation
|
This PR is a follow-up of PR #18107 which was a implementation in pure Python. @serhiy-storchaka wrote that he would prefer an implementation in C: so here you have. |
Sorry, something went wrong.
os.unsetenv() uses _wputenv() rather than SetEnvironmentVariableW(): _wputenv() updates the CRT, whereas SetEnvironmentVariableW() does not. Replace also lambda functions with regular functions to get named functions, to ease debug.
|
Some notes on Windows environment variables:
|
Sorry, something went wrong.
|
There are also "secure" (or "safe"?) (but not thread-safe) |
Sorry, something went wrong.
I created https://bugs.python.org/issue39420 to track this issue. |
Sorry, something went wrong.
|
I'm thinking aloud. If we switch Python to use the native API ( To support "=" at the beginning of the variable name, one option would be to use the native API ( I tested
|
Sorry, something went wrong.
The consequence for this is that in Vista and later
"=" is rejected by
CMD actually implements this all on its own. And it has a parsing bug that leads to displaying the 'hidden' variables if you run
Python is right. |
Sorry, something went wrong.
Oh right, nice :-) |
Sorry, something went wrong.
Do you mean |
Sorry, something went wrong.
|
int _wputenv(
const wchar_t *envstring
);https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/putenv-wputenv?view=vs-2019#syntax |
Sorry, something went wrong.
|
GetEnvironmentStringsA() and GetEnvironmentStringsW() result also contain variables with name starting with "=", like It seems like internally, Windows environment is a list of "name=value\0" strings. Variable name and value seem to be stored together as a single string. Moreover, after _wputenv("victor=secret"):
... in short, it doesn't seem possible to distinguish if "=" character belongs to the name or the value, except for the special case of name starting with "=". SetEnvironmentVariableW() allows a name starting with "=", but "=" is not allowed elsewhere in the same. SetEnvironmentVariableW("=a=b", "c") fails for example (WinError 87). The problem comes from _wputenv() API which takes a single argument. |
Sorry, something went wrong.
|
I failed to find CRT source code in my VS 2017 Community install. VC\crt\src directory is missing. But I found ReactOS implementation which gives me an idea on how it can be implemented and are the constraints: https://doxygen.reactos.org/df/def/putenv_8c.html#adea7d1267d47562084ac102de11a11fb
|
Sorry, something went wrong.
A valid environment block is also terminated by a final null character.
These are correct.
The The
There is no problem with |
Sorry, something went wrong.
Look in "%ProgramFiles(x86)%\Windows Kits\10\Source\10.0.[version]\ucrt\env". |
Sorry, something went wrong.
The ReactOS implementation of RtlQueryEnvironmentVariable_U looks correct to me, so I think the bug is in Vista's new In the loop body, they first increment |
Sorry, something went wrong.
|
Handling environment variables on Windows is more complex than what I expected. I start by reverting my previous change, to move back to the previous status quo: PR #18124. I would prefer to restart from the previous state, and try to handle all issues at once. |
Sorry, something went wrong.
|
This PR has some issues. I wrote PR #18163 which is simpler and so should be easier to review. |
Sorry, something went wrong.
os.unsetenv() uses _wputenv() rather than SetEnvironmentVariableW():
_wputenv() updates the CRT, whereas SetEnvironmentVariableW() does
not.
Replace also lambda functions with regular functions to get named
functions, to ease debug.
https://bugs.python.org/issue39413