Eryk Sun <eryk...@gmail.com> added the comment:
> 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.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue28824>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to