Author: Amaury Forgeot d'Arc <amaur...@gmail.com>
Branch: more-rposix
Changeset: r74342:356ea110dea9
Date: 2014-11-05 16:59 +0100
http://bitbucket.org/pypy/pypy/changeset/356ea110dea9/

Log:    Move os.open() to rposix.py. Much simpler, less magic.

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
@@ -43,6 +43,8 @@
     return space.str0_w(w_obj)
 
 class FileEncoder(object):
+    is_unicode = True
+
     def __init__(self, space, w_obj):
         self.space = space
         self.w_obj = w_obj
@@ -54,6 +56,8 @@
         return self.space.unicode0_w(self.w_obj)
 
 class FileDecoder(object):
+    is_unicode = False
+
     def __init__(self, space, w_obj):
         self.space = space
         self.w_obj = w_obj
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -8,6 +8,7 @@
     specialize, enforceargs, register_replacement_for)
 from rpython.rlib import jit
 from rpython.translator.platform import platform
+from rpython.rlib import rstring
 
 _WIN32 = sys.platform.startswith('win')
 UNDERSCORE_ON_WIN32 = '_' if _WIN32 else ''
@@ -146,6 +147,11 @@
 
 c_dup = external(UNDERSCORE_ON_WIN32 + 'dup', [rffi.INT], rffi.INT)
 c_dup2 = external(UNDERSCORE_ON_WIN32 + 'dup2', [rffi.INT, rffi.INT], rffi.INT)
+c_open = external(UNDERSCORE_ON_WIN32 + 'open',
+                  [rffi.CCHARP, rffi.INT, rffi.MODE_T], rffi.INT)
+# Win32 specific functions
+c_wopen = external(UNDERSCORE_ON_WIN32 + 'wopen',
+                   [rffi.CWCHARP, rffi.INT, rffi.MODE_T], rffi.INT)
 
 #___________________________________________________________________
 # Wrappers around posix functions, that accept either strings, or
@@ -159,12 +165,50 @@
     assert path is not None
     if isinstance(path, str):
         return path
+    elif isinstance(path, unicode):
+        # This never happens in PyPy's Python interpreter!
+        # Only in raw RPython code that uses unicode strings.
+        # We implement python2 behavior: silently convert to ascii.
+        return path.encode('ascii')
     else:
         return path.as_bytes()
 
 @specialize.argtype(0)
-def open(path, flags, mode):
-    return os.open(_as_bytes(path), flags, mode)
+def _as_bytes0(path):
+    res = _as_bytes(path)
+    rstring.check_str0(path)
+    return res
+
+@specialize.argtype(0)
+def _as_unicode(path):
+    assert path is not None
+    if isinstance(path, unicode):
+        return path
+    else:
+        return path.as_unicode()
+
+@specialize.argtype(0)
+def _as_unicode0(path):
+    res = _as_unicode(path)
+    rstring.check_str0(path)
+    return res
+
+# Returns True when the unicode function should be called:
+# - on Windows
+# - if the path is Unicode.
+if _WIN32:
+    @specialize.argtype(0)
+    def _prefer_unicode(path):
+        if isinstance(path, str):
+            return False
+        elif isinstance(path, unicode):
+            return True
+        else:
+            return path.is_unicode
+else:
+    @specialize.argtype(0)
+    def _prefer_unicode(path):
+        return False
 
 @specialize.argtype(0)
 def stat(path):
@@ -267,3 +311,15 @@
     error = c_dup2(fd, newfd)
     if error < 0:
         raise OSError(get_errno(), "dup2 failed")
+
+@register_replacement_for(os.open, sandboxed_name='ll_os.ll_os_open')
+@specialize.argtype(0)
+def open(path, flags, mode):
+    if _prefer_unicode(path):
+        fd = c_wopen(_as_unicode0(path), flags, mode)
+    else:
+        fd = c_open(_as_bytes0(path), flags, mode)
+    if fd < 0:
+        raise OSError(get_errno(), "open failed")
+    return intmask(fd)
+        
diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py
--- a/rpython/rlib/test/test_rposix.py
+++ b/rpython/rlib/test/test_rposix.py
@@ -45,7 +45,7 @@
     def test_open(self):
         def f():
             try:
-                fd = rposix.open(self.path, os.O_RDONLY, 0777)
+                fd = os.open(self.path, os.O_RDONLY, 0777)
                 try:
                     text = os.read(fd, 50)
                     return text
@@ -177,3 +177,9 @@
             os.dup(4)
             os.dup2(5, 6)
         compile(f, ())
+
+    def test_open(self):
+        def f():
+            os.open('/tmp/t', 0, 0)
+            os.open(u'/tmp/t', 0, 0)
+        compile(f, ())
diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py
--- a/rpython/rtyper/module/ll_os.py
+++ b/rpython/rtyper/module/ll_os.py
@@ -910,20 +910,6 @@
         return extdef([int, int, int], None, llimpl=c_setresgid_llimpl,
                       export_name='ll_os.ll_os_setresgid')
 
-    @registering_str_unicode(os.open)
-    def register_os_open(self, traits):
-        os_open = self.llexternal(traits.posix_function_name('open'),
-                                  [traits.CCHARP, rffi.INT, rffi.MODE_T],
-                                  rffi.INT)
-        def os_open_llimpl(path, flags, mode):
-            result = rffi.cast(lltype.Signed, os_open(path, flags, mode))
-            if result == -1:
-                raise OSError(rposix.get_errno(), "os_open failed")
-            return result
-
-        return extdef([traits.str0, int, int], int, traits.ll_os_name('open'),
-                      llimpl=os_open_llimpl)
-
     @registering_if(os, 'getloadavg')
     def register_os_getloadavg(self):
         AP = rffi.CArrayPtr(lltype.Float)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to