classification
Title: environment inspection and manipulation API is buggy, inconsistent with "Python philosophy" for wrapping native APIs
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.2, Python 3.1, Python 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: eric.araujo, exarkun
Priority: normal Keywords:

Created on 2009-01-08 22:08 by exarkun, last changed 2010-07-11 09:48 by BreamoreBoy.

Messages (1)
msg79448 - (view) Author: Jean-Paul Calderone (exarkun) * (Python committer) Date: 2009-01-08 22:08
According to a recent thread on python-dev, Python APIs with the same
name as native APIs can be trusted to just pass through to the platform
API call
(<http://mail.python.org/pipermail/python-dev/2009-January/084899.html>). 
This isn't the case for the environment APIs in the os module.  For
example, os.getenv doesn't always return the actual value of a key in
the environment.  Instead, it looks in the os.environ pseudo-dict to get
the answer.  This can be wrong because os.environ is a *copy* of the
environment which any non-Python API will use, and as a copy it can get
out of sync with the real environment.  One way it can get out of sync
is via os.environ.pop (at least on POSIX - os.environ has different
implementations on different platforms, I find the way an implementation
is selected to be rather confusing and I have not tracked down the
precise behavior for all platforms):

>>> import os
>>> os.environ.pop('PATH')
'/home/exarkun/.local/sbin:/home/exarkun/.local/bin:/home/exarkun/Projects/combinator_paths/bincache:/home/exarkun/.local/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games'
>>> os.getenv('PATH')
>>> os.system("echo $PATH")
/home/exarkun/.local/sbin:/home/exarkun/.local/bin:/home/exarkun/Projects/combinator_paths/bincache:/home/exarkun/.local/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games
0
>>> 

Another way is via calls to the platform environment manipulation APIs
(setenv, unsetenv or putenv).  These might be invoked by a third-party
library which is exposed to Python or via ctypes.

`environ“ itself is a C API, though it's a char**, whereas os.environ is
a Python dict.  It's probably convenient for os.environ to remain as a
dict, since that's so much simpler to manipulate and inspect than the C
data structure used.  However, it'd be good if were always in sync with
the real process environment.  A good way to do this would probably be
to stop maintaining a copy of the environment and always pass through to
one of the platform APIs to satisfy a method call onto it.
History
Date User Action Args
2010-07-11 09:48:11BreamoreBoysetversions: + Python 3.1, Python 2.7, Python 3.2
2009-09-27 16:42:50eric.araujosetnosy: + eric.araujo
2009-01-08 22:08:06exarkuncreate