[pypy-svn] r76161 - in pypy/branch/unicode_filename-2/pypy: rlib rlib/test rpython rpython/lltypesystem rpython/module
afa at codespeak.net
afa at codespeak.net
Mon Jul 12 22:01:57 CEST 2010
Author: afa
Date: Mon Jul 12 22:01:55 2010
New Revision: 76161
Added:
pypy/branch/unicode_filename-2/pypy/rlib/test/test_rposix.py
Modified:
pypy/branch/unicode_filename-2/pypy/rlib/rposix.py
pypy/branch/unicode_filename-2/pypy/rpython/extfunc.py
pypy/branch/unicode_filename-2/pypy/rpython/lltypesystem/rffi.py
pypy/branch/unicode_filename-2/pypy/rpython/module/ll_os.py
Log:
Add rlib.rposix.open(), which accept strings, and unicode "with default encoding".
The default implementation simply calls the encode() method and passes the
result to os.open(); but ll_os can provide a function that directly accepts
unicode.
Modified: pypy/branch/unicode_filename-2/pypy/rlib/rposix.py
==============================================================================
--- pypy/branch/unicode_filename-2/pypy/rlib/rposix.py (original)
+++ pypy/branch/unicode_filename-2/pypy/rlib/rposix.py Mon Jul 12 22:01:55 2010
@@ -3,6 +3,7 @@
from pypy.rpython.lltypesystem import lltype, ll2ctypes, rffi
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.objectmodel import specialize
class CConstantErrno(CConstant):
# these accessors are used when calling get_errno() or set_errno()
@@ -42,3 +43,13 @@
os.close(fd)
except OSError:
pass
+
+
+# pypy.rpython.module.ll_os.py may force the annotator to flow a different
+# function that directly handle unicode strings.
+ at specialize.argtype(0)
+def open(path, flags, mode):
+ if isinstance(path, str):
+ return os.open(path, flags, mode)
+ else:
+ return os.open(path.encode(), flags, mode)
Added: pypy/branch/unicode_filename-2/pypy/rlib/test/test_rposix.py
==============================================================================
--- (empty file)
+++ pypy/branch/unicode_filename-2/pypy/rlib/test/test_rposix.py Mon Jul 12 22:01:55 2010
@@ -0,0 +1,39 @@
+from pypy.rpython.test.test_llinterp import interpret
+from pypy.tool.udir import udir
+from pypy.rlib import rposix
+import os
+
+def ll_to_string(s):
+ return ''.join(s.chars)
+
+class TestPosixUnicode:
+ def test_access(self):
+ ufilename = (unicode(udir.join('test_open')) +
+ u'\u65e5\u672c.txt') # "Japan"
+ f = file(ufilename, 'w')
+ f.write("test")
+ f.close()
+ filename = str(udir.join('test_open'))
+
+ class UnicodeWithEncoding:
+ def __init__(self, unistr):
+ self.unistr = unistr
+
+ def encode(self):
+ from pypy.rlib.runicode import unicode_encode_utf_8
+ return unicode_encode_utf_8(self.unistr, len(self.unistr),
+ "strict")
+ path = UnicodeWithEncoding(ufilename)
+
+ def f():
+ try:
+ fd = rposix.open(path, os.O_RDONLY, 0777)
+ try:
+ text = os.read(fd, 50)
+ return text
+ finally:
+ os.close(fd)
+ except OSError:
+ return ''
+
+ assert ll_to_string(interpret(f, [])) == "test"
Modified: pypy/branch/unicode_filename-2/pypy/rpython/extfunc.py
==============================================================================
--- pypy/branch/unicode_filename-2/pypy/rpython/extfunc.py (original)
+++ pypy/branch/unicode_filename-2/pypy/rpython/extfunc.py Mon Jul 12 22:01:55 2010
@@ -52,7 +52,10 @@
return super(ExtRegistryEntry, self).__getattr__(attr)
raise exc, exc_inst, tb
-def registering(func):
+def registering(func, condition=True):
+ if not condition:
+ return lambda method: None
+
def decorator(method):
method._registering_func = func
return method
@@ -63,11 +66,9 @@
func = getattr(ns, name)
except AttributeError:
condition = False
+ func = None
- if condition:
- return registering(func)
- else:
- return lambda method: None
+ return registering(func, condition=condition)
class LazyRegisteringMeta(type):
def __new__(self, _name, _type, _vars):
Modified: pypy/branch/unicode_filename-2/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/unicode_filename-2/pypy/rpython/lltypesystem/rffi.py (original)
+++ pypy/branch/unicode_filename-2/pypy/rpython/lltypesystem/rffi.py Mon Jul 12 22:01:55 2010
@@ -176,6 +176,15 @@
# XXX leaks if a str2charp() fails with MemoryError
# and was not the first in this function
freeme = arg
+ elif TARGET == CWCHARP:
+ if arg is None:
+ arg = lltype.nullptr(CWCHARP.TO) # None => (wchar_t*)NULL
+ freeme = arg
+ elif isinstance(arg, unicode):
+ arg = unicode2wcharp(arg)
+ # XXX leaks if a unicode2wcharp() fails with MemoryError
+ # and was not the first in this function
+ freeme = arg
elif _isfunctype(TARGET) and not _isllptr(arg):
# XXX pass additional arguments
if invoke_around_handlers:
Modified: pypy/branch/unicode_filename-2/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/branch/unicode_filename-2/pypy/rpython/module/ll_os.py (original)
+++ pypy/branch/unicode_filename-2/pypy/rpython/module/ll_os.py Mon Jul 12 22:01:55 2010
@@ -7,7 +7,7 @@
import os, sys, errno
from pypy.rpython.module.support import ll_strcpy, OOSupport
-from pypy.tool.sourcetools import func_with_new_name
+from pypy.tool.sourcetools import func_with_new_name, func_renamer
from pypy.rlib.rarithmetic import r_longlong
from pypy.rpython.extfunc import BaseLazyRegistering
from pypy.rpython.extfunc import registering, registering_if, extdef
@@ -26,7 +26,41 @@
from pypy.rpython.lltypesystem.rstr import STR
from pypy.rpython.annlowlevel import llstr
from pypy.rlib import rgc
-from pypy.rlib.objectmodel import keepalive_until_here
+from pypy.rlib.objectmodel import keepalive_until_here, specialize
+from pypy.rlib.unroll import unrolling_iterable
+
+def registering_unicode_version(func, nbargs, argnums, condition=True):
+ """
+ Registers an implementation of func() which directly accepts unicode
+ strings. Replaces the corresponding function in pypy.rlib.rposix.
+ """
+ def unicodefunc(*args):
+ raise NotImplementedError
+
+ argnum = argnums[0]
+ unrolling_args = unrolling_iterable(enumerate([i in argnums
+ for i in range(nbargs)]))
+
+ func_name = func.__name__
+ rposix_func = getattr(rposix, func_name)
+
+ @specialize.argtype(*argnums)
+ @func_renamer(func.__name__)
+ def new_func(*args):
+ if isinstance(args[argnum], str):
+ return func(*args)
+ else:
+ real_args = ()
+ for i, isunicode in unrolling_args:
+ if isunicode:
+ real_args += (args[i].unistr,)
+ else:
+ real_args += (args[i],)
+ return unicodefunc(*real_args)
+ if condition:
+ rposix_func._flowspace_rewrite_directly_as_ = new_func
+
+ return registering(unicodefunc, condition=condition)
posix = __import__(os.name)
@@ -705,6 +739,20 @@
return extdef([str, int, int], int, "ll_os.ll_os_open",
llimpl=os_open_llimpl, oofakeimpl=os_open_oofakeimpl)
+ @registering_unicode_version(os.open, 3, [0], sys.platform=='win32')
+ def register_os_open_unicode(self):
+ os_wopen = self.llexternal(underscore_on_windows+'wopen',
+ [rffi.CWCHARP, rffi.INT, rffi.MODE_T],
+ rffi.INT)
+ def os_wopen_llimpl(path, flags, mode):
+ result = rffi.cast(rffi.LONG, os_wopen(path, flags, mode))
+ if result == -1:
+ raise OSError(rposix.get_errno(), "os_open failed")
+ return result
+
+ return extdef([unicode, int, int], int, "ll_os.ll_os_wopen",
+ llimpl=os_wopen_llimpl)
+
# ------------------------------- os.read -------------------------------
@registering(os.read)
More information about the Pypy-commit
mailing list