Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why python uppercases all environment variables in windows

Tags:

python

windows

Is there any reason why os.environ contains all environment variables uppercase on Windows?, I don't understand why (only on windows) it doesn't load them on using the same case as it is defined ?

Is there an equivalent implementation of os.environment that loads the environment variable information without modifying them for Windows?

thanks

like image 688
MariangeMarcano Avatar asked Sep 26 '13 08:09

MariangeMarcano


2 Answers

Because Windows environment variables are case insensitive, but a Python dictionary is case sensitive. By uppercasing all entries, you ensure that you'll always be able to match entries.

Quoting from the Python os.py source code:

elif name in ('os2', 'nt'):  # Where Env Var Names Must Be UPPERCASE
    # But we store them as upper case

# ... 

else:  # Where Env Var Names Can Be Mixed Case

Note that the os.environ object translates all access to uppercase, including searches:

def __setitem__(self, key, item):
    putenv(key, item)
    self.data[key.upper()] = item
def __getitem__(self, key):
    return self.data[key.upper()]

# ...

def has_key(self, key):
    return key.upper() in self.data
def __contains__(self, key):
    return key.upper() in self.data
def get(self, key, failobj=None):
    return self.data.get(key.upper(), failobj)

This means that if a program fails to find os.environ['windir'], then the value is not set.

If you have to have access to the original values, grab them from the nt module:

import nt
nt.environ

That's the raw initial dictionary as passed in by the OS, unaltered:

>>> import nt
>>> sorted(nt.environ.keys())
['ALLUSERSPROFILE', 'APPDATA', 'COMPUTERNAME', 'ComSpec', 'CommonProgramFiles', 'CommonProgramFiles(x86)', 'CommonProgramW6432', 'FP_NO_HOST_CHECK', 'HOMEDRIVE', 'HOMEPATH', 'LOCALAPPDATA', 'LOGONSERVER', 'NUMBER_OF_PROCESSORS', 'OS', 'PATHEXT', 'PROCESSOR_ARCHITECTURE', 'PROCESSOR_IDENTIFIER', 'PROCESSOR_LEVEL', 'PROCESSOR_REVISION', 'PROMPT', 'PSModulePath', 'PUBLIC', 'Path', 'ProgramData', 'ProgramFiles', 'ProgramFiles(x86)', 'ProgramW6432', 'SESSIONNAME', 'SSH_AUTH_SOCK', 'SystemDrive', 'SystemRoot', 'TEMP', 'TMP', 'USERDNSDOMAIN', 'USERDOMAIN', 'USERNAME', 'USERPROFILE', 'windir', 'windows_tracing_flags', 'windows_tracing_logfile']
like image 110
Martijn Pieters Avatar answered Sep 28 '22 10:09

Martijn Pieters


Windows case insensitivity is a pain. Why would they do that? You can understand why searches should be case insensitive, but in most cases defined content should keep the exact value. Why? Well from experience it causes so many problems. I've never come across an issue where I've thought, "oh why wasn't that uppercased or lowercased?".

From a Python point of view, why would they do that? Windows stores the key case sensitively, I'm guessing it is only some functions that get the value in a case insensitive manner, because I know for a fact that not all access functions do. I think MKS can tell the difference.

Don't force platform specific behaviour (and be careful with forcing other behaviour) in an interface. Provide an alternative method to force case insensitivity, if required.

like image 30
Tom Lucas Avatar answered Sep 28 '22 12:09

Tom Lucas