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