This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients benrg, eryksun, paul.moore, r.david.murray, steve.dower, tim.golden, tzickel, zach.ware
Date 2022-02-27.05:47:18
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1645940838.4.0.177709998636.issue28824@roundup.psfhosted.org>
In-reply-to
Content
> I think there should be a public class like this.

I wrote a basic implementation of _CaseInsensitiveString under the assumption that it's hidden behind the __getitem__(), __setitem__(), and __delitem__() methods of the _Environ class. I don't want to complicate the implementation.

The problem of case-insensitive names in file/registry paths and environment variables should be addressed with ntpath.normcase(). This should be based on WinAPI LCMapStringEx() with LOCALE_NAME_INVARIANT and LCMAP_UPPERCASE. The current implementation of ntpath.normcase() uses str.lower(), which depends on Python's Unicode database. This possibly differs from what Windows considers to be lower case in the invariant locale. It's also wrong because Windows uses upper case for cases-insensitive comparisons, which matters when sorting names. See bpo-42658.

> Right now, it's not a good workaround because it contains the 
> environment at the time the interpreter was started, not the 
> current environment.

Note that in some cases the "current environment" is the process environment, which isn't necessarily consistent with os.environ on any platform.

In POSIX, posix.environ is created from C environ, which is kept in sync with changes to posix.environ via C putenv() and unsetenv(). However, directly calling os.putenv() or os.unsetenv(), or the underlying C functions, modifies the process environment without changing posix.environ. If subprocess.Popen() is called without overriding env, the child inherits the process environment, not posix.environ.

In Windows, os.environ is created from nt.environ, with variables names converted to upper case. nt.environ is created from C _wenviron, which is created from the process environment, as returned by WinAPI GetEnvironmentStringsW(), except with variable names that begin with "=" filtered out. os.putenv() and os.unsetenv() are based on C _wputenv(), which updates C _wenviron and also updates the process environment via WinAPI SetEnvironmentVariableW(). If either os.putenv() or os.unsetenv() is called directly, or _wputenv() at a lower level, then the variables in C _wenviron (not just the letter case of the names) will be out of sync with os.environ. Additionally, if SetEnvironmentVariableW() is called directly to set or unset a variable, then both os.environ and C _wenviron will be out of sync with the process environment. If subprocess.Popen() is called without overriding env, the child inherits the process environment, not os.environ or C _wenviron.
History
Date User Action Args
2022-02-27 05:47:18eryksunsetrecipients: + eryksun, paul.moore, tim.golden, r.david.murray, benrg, zach.ware, steve.dower, tzickel
2022-02-27 05:47:18eryksunsetmessageid: <1645940838.4.0.177709998636.issue28824@roundup.psfhosted.org>
2022-02-27 05:47:18eryksunlinkissue28824 messages
2022-02-27 05:47:18eryksuncreate