[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 &#8220;segment&#8221; 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