[pypy-commit] pypy stdlib-2.7.3: CPython Issue #13415: os.unsetenv() doesn't ignore errors anymore.

amauryfa noreply at buildbot.pypy.org
Thu Jun 14 00:42:01 CEST 2012


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: stdlib-2.7.3
Changeset: r55656:f233d4735772
Date: 2012-06-13 22:52 +0200
http://bitbucket.org/pypy/pypy/changeset/f233d4735772/

Log:	CPython Issue #13415: os.unsetenv() doesn't ignore errors anymore.

diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py
--- a/pypy/module/posix/interp_posix.py
+++ b/pypy/module/posix/interp_posix.py
@@ -14,6 +14,10 @@
 
 import os, sys
 
+_WIN32 = sys.platform == 'win32'
+if _WIN32:
+    from pypy.rlib.rwin32 import _MAX_ENV
+    
 c_int = "c_int"
 
 # CPython 2.7 semantics are too messy to follow exactly,
@@ -417,7 +421,7 @@
     else:
         return space.wrap(cur)
 
-if sys.platform == 'win32':
+if _WIN32:
     def getcwdu(space):
         """Return the current working directory as a unicode string."""
         try:
@@ -510,6 +514,9 @@
 @unwrap_spec(name='str0', value='str0')
 def putenv(space, name, value):
     """Change or add an environment variable."""
+    if _WIN32 and len(name) > _MAX_ENV:
+        raise OperationError(space.w_ValueError, space.wrap(
+                "the environment variable is longer than %d bytes" % _MAX_ENV))
     try:
         os.environ[name] = value
     except OSError, e:
diff --git a/pypy/rlib/rwin32.py b/pypy/rlib/rwin32.py
--- a/pypy/rlib/rwin32.py
+++ b/pypy/rlib/rwin32.py
@@ -76,7 +76,7 @@
             "MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)")
 
         defines = """FORMAT_MESSAGE_ALLOCATE_BUFFER FORMAT_MESSAGE_FROM_SYSTEM
-                       MAX_PATH
+                       MAX_PATH _MAX_ENV
                        WAIT_OBJECT_0 WAIT_TIMEOUT INFINITE
                        ERROR_INVALID_HANDLE
                        DELETE READ_CONTROL SYNCHRONIZE WRITE_DAC
diff --git a/pypy/rpython/module/ll_os_environ.py b/pypy/rpython/module/ll_os_environ.py
--- a/pypy/rpython/module/ll_os_environ.py
+++ b/pypy/rpython/module/ll_os_environ.py
@@ -31,9 +31,11 @@
 
     def delitem(self, obj, key):
         # in the RPython program, 'del os.environ[key]' is redirected here
-        if r_getenv(key) is None:
+        absent = r_getenv(key) is None
+        # Always call unsetenv(), to get eventual OSErrors
+        r_unsetenv(key)
+        if absent:
             raise KeyError
-        r_unsetenv(key)
 
     def get_keys(self, obj):
         # 'os.environ.keys' is redirected here - note that it's the getattr
diff --git a/pypy/rpython/module/test/test_ll_os_environ.py b/pypy/rpython/module/test/test_ll_os_environ.py
--- a/pypy/rpython/module/test/test_ll_os_environ.py
+++ b/pypy/rpython/module/test/test_ll_os_environ.py
@@ -11,3 +11,20 @@
     f = compile(foo, [int], backendopt=False)
     assert f(1) > 0
     
+def test_unset_error():
+
+    def foo(x):
+        if x:
+            os.environ['TEST'] = 'STRING'
+            assert os.environ['TEST'] == 'STRING'
+            del os.environ['TEST']
+            try:
+                del os.environ['key=']
+            except OSError:
+                return 1
+            return 2
+        else:
+            return 0
+    f = compile(foo, [int], backendopt=False)
+    assert f(1) == 1
+    


More information about the pypy-commit mailing list