[Python-bugs-list] [ python-Bugs-463506 ] reload(os) fails for os.environ
noreply@sourceforge.net
noreply@sourceforge.net
Sat, 22 Sep 2001 21:45:08 -0700
Bugs item #463506, was opened at 2001-09-21 03:05
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=463506&group_id=5470
Category: Windows
Group: Python 2.1.1
Status: Closed
Resolution: Wont Fix
Priority: 5
Submitted By: Nobody/Anonymous (nobody)
Assigned to: Mark Hammond (mhammond)
Summary: reload(os) fails for os.environ
Initial Comment:
I used function KERNEL32::SetEnvironmentVariableA
via Dynawrap.dll from
http://cwashington.netreach.net/main_site/
downloads/default.asp?topic=a-m
to add an new entry.
Then I tested the result with a scripting host
component and the new entry was shown. But not working
was this:
reload(os)
os.environ
PythonWin 2.1 (#15, Jun 18 2001, 21:42:28) [MSC 32 bit
(Intel)] on win32.
Portions Copyright 1994-2001 Mark Hammond
(MarkH@ActiveState.com) - see 'Help/About PythonWin'
for further copyright information.
>>> import os
>>> os.environ
{'SNDSCAPE': 'C:\WINDOWS', 'CMDLINE': 'WIN', 'PATH': '
C:\PROGRAMME\PYTHON21
\;C:\WINDOWS;C:\WINDOWS\COMMAND', 'TEMP': 'C:\WIND
OWS\TEMP', 'COMSPEC': 'C:\WINDOWS\COMMAND.COM', 'PRO
MPT': '$p$g', 'WINBOOTDIR': 'C:\WINDOWS', 'WINDIR': 'C
:\WINDOWS', 'TMP': 'C:\WINDOWS\TEMP'}
>>>
>>> from win32com.client import Dispatch
>>> dw = Dispatch("DynamicWrapper")
>>> dw.Register
("KERNEL32.DLL", "SetEnvironmentVariableA", "i=ss", "f=
s", "r=l")
1
>>> dw.SetEnvironmentVariableA
("MyNewEntry", "MyNewValue")
1
>>> reload(os)
<module 'os' from 'c:\programme\python21\lib\os.pyc'>
>>> os.environ
{'SNDSCAPE': 'C:\WINDOWS', 'CMDLINE': 'WIN', 'PATH': '
C:\PROGRAMME\PYTHON21
\;C:\WINDOWS;C:\WINDOWS\COMMAND', 'TEMP': 'C:\WIND
OWS\TEMP', 'COMSPEC': 'C:\WINDOWS\COMMAND.COM', 'PRO
MPT': '$p$g', 'WINBOOTDIR': 'C:\WINDOWS', 'WINDIR': 'C
:\WINDOWS', 'TMP': 'C:\WINDOWS\TEMP'}
>>>
>>> sh = Dispatch("WScript.Shell")
>>> for string in sh.Environment._NewEnum():
... print string
...
TMP=C:\WINDOWS\TEMP
TEMP=C:\WINDOWS\TEMP
PROMPT=$p$g
winbootdir=C:\WINDOWS
COMSPEC=C:\WINDOWS\COMMAND.COM
PATH=C:\PROGRAMME\PYTHON21
\;C:\WINDOWS;C:\WINDOWS\COMMAND
CMDLINE=WIN
windir=C:\WINDOWS
SNDSCAPE=C:\WINDOWS
MYNEWENTRY=MyNewValue
>>>
----------------------------------------------------------------------
>Comment By: Mark Hammond (mhammond)
Date: 2001-09-22 21:45
Message:
Logged In: YES
user_id=14198
I think the SDK description Tim posted was clear that
setenv does not modify the process environment. To prove
this, I wrote the test code at the end (and output past it).
It shows that using "::SetEnvironmentVariable()" will not
have the value reflected in the CRTL (ie, getenv() will not
see the new value)
However, using putenv() *does* reflect the value back to
the Win32 API - so GetEnvironmentVariable *does* see the
value set by putenv.
So I think Python is using the correct API, and can't fix
the behaviour.
int main()
{
static char buffer[128];
char * val = getenv("FOO");
printf("When starting, FOO=%s\n", val);
SetEnvironmentVariable("FOO", "SetEnvironmentVariable");
GetEnvironmentVariable("FOO", buffer, sizeof
(buffer)/sizeof(buffer[0]));
val = buffer;
printf("After set, GetEnvironmentVariable reports FOO=%
s\n", val);
val = getenv("FOO");
printf("After set, getenv reports FOO=%s\n", val);
putenv("FOO=_putenv");
GetEnvironmentVariable("FOO", buffer, sizeof
(buffer)/sizeof(buffer[0]));
val = buffer;
printf("After _putenv set, GetEnvironmentVariable
reports FOO=%s\n", val);
val = getenv("FOO");
printf("After _putenv set, getenv reports FOO=%s\n",
val);
return 0;
}
Output:
When starting, FOO=(null)
After set, GetEnvironmentVariable reports
FOO=SetEnvironmentVariable
After set, getenv reports FOO=(null)
After _putenv set, GetEnvironmentVariable reports
FOO=_putenv
After _putenv set, getenv reports FOO=_putenv
----------------------------------------------------------------------
Comment By: Guido van Rossum (gvanrossum)
Date: 2001-09-22 10:33
Message:
Logged In: YES
user_id=6380
The reason is trivial. reload(os) doesn't magically cause
reload(nt), and it's the nt module (whose source is
posixmodule.c) that computes the 'environ' dictionary. I
betcha a dollar that if you reload(nt) and then reload(os),
the environment is fixed. But why would you want to do
that? Changing os.environ should automatically call
_putenv(); if it doesn't, submit a separate bug report.
The MS docs are trying to explain that the environment
semantics are the same as in Unix (you can't change your
shell's environment, but child processes do inherit yours).
In my experience envars work fine in Windows.
----------------------------------------------------------------------
Comment By: Tim Peters (tim_one)
Date: 2001-09-21 17:29
Message:
Logged In: YES
user_id=31435
Ah! Good call. WRT VC's putenv, the MS docs say:
"""
_putenv and _wputenv affect only the environment that is
local to the current process; you cannot use them to modify
the command-level environment. That is, these functions
operate only on data structures accessible to the run-time
library and not on the environment “segment” created for a
process by the operating system. When the current process
terminates, the environment reverts to the level of the
calling process (in most cases, the operating-system
level). However, the modified environment can be passed to
any new processes created by _spawn, _exec, or system, and
these new processes get any new items added by _putenv and
_wputenv.
"""
Sounds like the msvcrt-level env functions work with a copy
of the process env block captured at process creation time.
As usual, a Bad Idea to try to use envars on Windows ...
----------------------------------------------------------------------
Comment By: Mark Hammond (mhammond)
Date: 2001-09-21 17:01
Message:
Logged In: YES
user_id=14198
The complaint is that when the environment is set via the
win32 API, os.environ appears to not pick up the new
setting.
I have no idea why this is, but it is not Python's fault.
Python uses the C runtime library, and there i snot much we
can do about that. I don't have time to try and locate the
CRTL source code and figure out why either. Marking
as "Wont Fix"
----------------------------------------------------------------------
Comment By: Tim Peters (tim_one)
Date: 2001-09-21 14:47
Message:
Logged In: YES
user_id=31435
Reassigned to MarkH. I haven't figured out what the
complaint is, but it looks like it has to do with the Win32
extensions.
----------------------------------------------------------------------
Comment By: Nobody/Anonymous (nobody)
Date: 2001-09-21 05:00
Message:
Logged In: NO
This is an altenative way to change the environment:
from win32com.client import Dispatch
sh = Dispatch("WScript.Shell")
sh.Environment['MYNEWENTRY'] = "bla-bla"
print sh.Environment['MYNEWENTRY']
----------------------------------------------------------------------
Comment By: Nobody/Anonymous (nobody)
Date: 2001-09-21 03:18
Message:
Logged In: NO
Markus_Daniel@gmx.de
----------------------------------------------------------------------
Comment By: Nobody/Anonymous (nobody)
Date: 2001-09-21 03:08
Message:
Logged In: NO
This Bug was submitted by Markus Daniel (Spacy73)
----------------------------------------------------------------------
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=463506&group_id=5470