Author: Amaury Forgeot d'Arc <[email protected]>
Branch: 
Changeset: r47846:787a29a88622
Date: 2011-10-07 00:55 +0200
http://bitbucket.org/pypy/pypy/changeset/787a29a88622/

Log:    accept unicode arguments in posix.execv and posix.execve. encode
        with sys.getfilesystemencoding()

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
@@ -10,6 +10,7 @@
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rpython.tool import rffi_platform
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.module.sys.interp_encoding import getfilesystemencoding
 
 import os, sys
 _WIN = sys.platform == 'win32'
@@ -32,17 +33,19 @@
             raise OperationError(space.w_OverflowError,
                                  space.wrap("integer out of range"))
 
+def fsencode_w(space, w_obj):
+    if space.isinstance_w(w_obj, space.w_unicode):
+        w_obj = space.call_method(w_obj, 'encode',
+                                  getfilesystemencoding(space))
+    return space.str_w(w_obj)
+
 class FileEncoder(object):
     def __init__(self, space, w_obj):
         self.space = space
         self.w_obj = w_obj
 
     def as_bytes(self):
-        from pypy.module.sys.interp_encoding import getfilesystemencoding
-        space = self.space
-        w_bytes = space.call_method(self.w_obj, 'encode',
-                                    getfilesystemencoding(space))
-        return space.str_w(w_bytes)
+        return fsencode_w(self.space, self.w_obj)
 
     def as_unicode(self):
         return self.space.unicode_w(self.w_obj)
@@ -56,7 +59,6 @@
         return self.space.str_w(self.w_obj)
 
     def as_unicode(self):
-        from pypy.module.sys.interp_encoding import getfilesystemencoding
         space = self.space
         w_unicode = space.call_method(self.w_obj, 'decode',
                                       getfilesystemencoding(space))
@@ -536,7 +538,6 @@
 
 The list is in arbitrary order.  It does not include the special
 entries '.' and '..' even if they are present in the directory."""
-    from pypy.module.sys.interp_encoding import getfilesystemencoding
     try:
         if space.isinstance_w(w_dirname, space.w_unicode):
             dirname = FileEncoder(space, w_dirname)
@@ -734,8 +735,7 @@
 def _exit(space, status):
     os._exit(status)
 
-@unwrap_spec(command=str)
-def execv(space, command, w_args):
+def execv(space, w_command, w_args):
     """ execv(path, args)
 
 Execute an executable path with arguments, replacing current process.
@@ -743,12 +743,13 @@
         path: path of executable file
         args: iterable of strings
     """
+    command = fsencode_w(space, w_command)
     try:
         args_w = space.unpackiterable(w_args)
         if len(args_w) < 1:
             w_msg = space.wrap("execv() must have at least one argument")
             raise OperationError(space.w_ValueError, w_msg)
-        args = [space.str_w(w_arg) for w_arg in args_w]
+        args = [fsencode_w(space, w_arg) for w_arg in args_w]
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
@@ -759,8 +760,7 @@
     except OSError, e:
         raise wrap_oserror(space, e)
 
-@unwrap_spec(command=str)
-def execve(space, command, w_args, w_env):
+def execve(space, w_command, w_args, w_env):
     """ execve(path, args, env)
 
 Execute a path with arguments and environment, replacing current process.
@@ -769,7 +769,8 @@
         args: iterable of arguments
         env: dictionary of strings mapping to strings
     """
-    args = [space.str_w(w_arg) for w_arg in space.unpackiterable(w_args)]
+    command = fsencode_w(space, w_command)
+    args = [fsencode_w(space, w_arg) for w_arg in space.unpackiterable(w_args)]
     env = {}
     w_keys = space.call_method(w_env, 'keys')
     for w_key in space.unpackiterable(w_keys):
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
@@ -415,6 +415,20 @@
                 else:
                     py.test.fail("didn't raise")
 
+        def test_execv_unicode(self):
+            os = self.posix
+            import sys
+            if not hasattr(os, "fork"):
+                skip("Need fork() to test execv()")
+            pid = os.fork()
+            if pid == 0:
+                os.execv(u"/bin/sh", ["sh", "-c",
+                                      u"echo caf\xe9 \u1234 > onefile"])
+            os.waitpid(pid, 0)
+            output = u"caf\xe9 \u1234\n".encode(sys.getfilesystemencoding())
+            assert open("onefile").read() == output
+            os.unlink("onefile")
+
         def test_execve(self):
             os = self.posix
             if not hasattr(os, "fork"):
@@ -425,6 +439,21 @@
             os.waitpid(pid, 0)
             assert open("onefile").read() == "xxx"
             os.unlink("onefile")
+
+        def test_execve_unicode(self):
+            os = self.posix
+            import sys
+            if not hasattr(os, "fork"):
+                skip("Need fork() to test execve()")
+            pid = os.fork()
+            if pid == 0:
+                os.execve(u"/bin/sh", ["sh", "-c",
+                                      u"echo caf\xe9 \u1234 > onefile"],
+                          {'ddd': 'xxx'})
+            os.waitpid(pid, 0)
+            output = u"caf\xe9 \u1234\n".encode(sys.getfilesystemencoding())
+            assert open("onefile").read() == output
+            os.unlink("onefile")
         pass # <- please, inspect.getsource(), don't crash
 
     if hasattr(__import__(os.name), "spawnv"):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to