Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r63515:60f1685169d9
Date: 2013-04-19 15:15 -0700
http://bitbucket.org/pypy/pypy/changeset/60f1685169d9/
Log: use wide environ APIs on windows
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
@@ -12,7 +12,7 @@
_WIN32 = sys.platform == 'win32'
if _WIN32:
- from rpython.rlib.rwin32 import _MAX_ENV
+ from rpython.rlib import rwin32
c_int = "c_int"
@@ -481,6 +481,7 @@
self.w_environ = space.newdict()
self.random_context = rurandom.init_urandom()
def startup(self, space):
+ space.call_method(self.w_environ, 'clear')
_convertenviron(space, self.w_environ)
def _freeze_(self):
# don't capture the environment in the translated pypy
@@ -493,29 +494,46 @@
def get(space):
return space.fromcache(State)
-def _convertenviron(space, w_env):
- space.call_method(w_env, 'clear')
- for key, value in os.environ.items():
- space.setitem(w_env, space.wrapbytes(key), space.wrapbytes(value))
+if _WIN32:
+ def _convertenviron(space, w_env):
+ # _wenviron must be initialized in this way if the program is
+ # started through main() instead of wmain()
+ rwin32._wgetenv(u"")
+ for key, value in rwin32._wenviron_items():
+ space.setitem(w_env, space.wrap(key), space.wrap(value))
-def putenv(space, w_name, w_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:
- dispatch_filename_2(rposix.putenv)(space, w_name, w_value)
- except OSError, e:
- raise wrap_oserror(space, e)
+ @unwrap_spec(name=unicode, value=unicode)
+ def putenv(space, name, value):
+ """Change or add an environment variable."""
+ # len includes space for '=' and a trailing NUL
+ if len(name) + len(value) + 2 > rwin32._MAX_ENV:
+ msg = ("the environment variable is longer than %d characters" %
+ rwin32._MAX_ENV)
+ raise OperationError(space.w_ValueError, space.wrap(msg))
+ try:
+ rwin32._wputenv(name, value)
+ except OSError, e:
+ raise wrap_oserror(space, e)
+else:
+ def _convertenviron(space, w_env):
+ for key, value in os.environ.items():
+ space.setitem(w_env, space.wrapbytes(key), space.wrapbytes(value))
-def unsetenv(space, w_name):
- """Delete an environment variable."""
- try:
- dispatch_filename(rposix.unsetenv)(space, w_name)
- except KeyError:
- pass
- except OSError, e:
- raise wrap_oserror(space, e)
+ def putenv(space, w_name, w_value):
+ """Change or add an environment variable."""
+ try:
+ dispatch_filename_2(rposix.putenv)(space, w_name, w_value)
+ except OSError, e:
+ raise wrap_oserror(space, e)
+
+ def unsetenv(space, w_name):
+ """Delete an environment variable."""
+ try:
+ dispatch_filename(rposix.unsetenv)(space, w_name)
+ except KeyError:
+ pass
+ except OSError, e:
+ raise wrap_oserror(space, e)
@unwrap_spec(w_dirname=WrappedDefault(u"."))
diff --git a/pypy/module/posix/test/test_posix2.py
b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -938,12 +938,27 @@
cls.w_path = space.wrap(str(path))
def test_environ(self):
- posix = self.posix
+ import sys
+ environ = self.posix.environ
+ item_type = str if sys.platform.startswith('win') else bytes
+ for k, v in environ.items():
+ assert type(k) is item_type
+ assert type(v) is item_type
+ name = next(iter(environ))
+ assert environ[name] is not None
+ del environ[name]
+ raises(KeyError, lambda: environ[name])
+
+ @py.test.mark.dont_track_allocations('putenv intentionally keeps strings
alive')
+ def test_environ_nonascii(self):
os = self.os
- assert posix.environ[b'PATH']
- del posix.environ[b'PATH']
- def fn(): posix.environ[b'PATH']
- raises(KeyError, fn)
+ name, value = 'PYPY_TEST_日本', 'foobar日本'
+ os.environ[name] = value
+ assert os.environ[name] == value
+ assert os.getenv(name) == value
+ del os.environ[name]
+ assert os.environ.get(name) is None
+ assert os.getenv(name) is None
if hasattr(__import__(os.name), "unsetenv"):
def test_unsetenv_nonexisting(self):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit