Author: Amaury Forgeot d'Arc <[email protected]>
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
+
[email protected](0)
+def _as_unicode(path):
+ assert path is not None
+ if isinstance(path, unicode):
+ return path
+ else:
+ return path.as_unicode()
+
[email protected](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')
[email protected](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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit