[pypy-svn] r64565 - in pypy/branch/unicode_filename/pypy: module/posix rpython/lltypesystem rpython/module
afa at codespeak.net
afa at codespeak.net
Wed Apr 22 02:05:23 CEST 2009
Author: afa
Date: Wed Apr 22 02:05:23 2009
New Revision: 64565
Modified:
pypy/branch/unicode_filename/pypy/module/posix/interp_posix.py
pypy/branch/unicode_filename/pypy/rpython/lltypesystem/rffi.py
pypy/branch/unicode_filename/pypy/rpython/module/ll_os.py
pypy/branch/unicode_filename/pypy/rpython/module/ll_os_stat.py
Log:
Start accepting both str and unicode for filenames.
This does not disturb the ll functions too much,
what I don't like is that functions like os.stat cannot have a _annspecialcase_ attribute;
the "wrapper" function has to fish the lltypeimpl function.
Modified: pypy/branch/unicode_filename/pypy/module/posix/interp_posix.py
==============================================================================
--- pypy/branch/unicode_filename/pypy/module/posix/interp_posix.py (original)
+++ pypy/branch/unicode_filename/pypy/module/posix/interp_posix.py Wed Apr 22 02:05:23 2009
@@ -6,10 +6,11 @@
from pypy.rpython.module.ll_os import RegisterOs
from pypy.rpython.module import ll_os_stat
from pypy.rpython.lltypesystem import lltype
+from pypy.rpython import extregistry
import os, sys
_WIN = sys.platform == 'win32'
-
+
def open(space, fname, flag, mode=0777):
"""Open a file (for low level IO).
Return a file descriptor (a small integer)."""
@@ -143,7 +144,23 @@
return build_stat_result(space, st)
fstat.unwrap_spec = [ObjSpace, int]
-def stat(space, path):
+if _WIN:
+ def wrapper(fn):
+ impl = extregistry.lookup(fn).lltypeimpl
+ def f(space, w_path, args):
+ if space.is_true(space.isinstance(w_path, space.w_unicode)):
+ return impl(space.unicode_w(w_path), *args)
+ else:
+ return impl(space.str_w(w_path), *args)
+ return f
+else:
+ def wrapper(fn):
+ def f(space, w_path, args):
+ return fn(space.str_w(w_path), *args)
+ return f
+wrapper._annspecialcase_ = 'specialize:memo'
+
+def stat(space, w_path):
"""Perform a stat system call on the given path. Return an object
with (at least) the following attributes:
st_mode
@@ -159,22 +176,22 @@
"""
try:
- st = os.stat(path)
+ st = wrapper(os.stat)(space, w_path, ())
except OSError, e:
raise wrap_oserror(space, e)
else:
return build_stat_result(space, st)
-stat.unwrap_spec = [ObjSpace, str]
+stat.unwrap_spec = [ObjSpace, W_Root]
-def lstat(space, path):
+def lstat(space, w_path):
"Like stat(path), but do no follow symbolic links."
try:
- st = os.lstat(path)
+ st = wrapper(os.lstat)(space, w_path, ())
except OSError, e:
raise wrap_oserror(space, e)
else:
return build_stat_result(space, st)
-lstat.unwrap_spec = [ObjSpace, str]
+lstat.unwrap_spec = [ObjSpace, W_Root]
class StatState(object):
def __init__(self, space):
@@ -299,21 +316,21 @@
return space.wrap(cur)
getcwd.unwrap_spec = [ObjSpace]
-def chdir(space, path):
+def chdir(space, w_path):
"""Change the current working directory to the specified path."""
try:
- os.chdir(path)
+ wrapper(os.chdir)(space, w_path, ())
except OSError, e:
raise wrap_oserror(space, e)
-chdir.unwrap_spec = [ObjSpace, str]
+chdir.unwrap_spec = [ObjSpace, W_Root]
-def mkdir(space, path, mode=0777):
+def mkdir(space, w_path, mode=0777):
"""Create a directory."""
try:
- os.mkdir(path, mode)
+ wrapper(os.mkdir)(space, w_path, (mode,))
except OSError, e:
raise wrap_oserror(space, e)
-mkdir.unwrap_spec = [ObjSpace, str, int]
+mkdir.unwrap_spec = [ObjSpace, W_Root, int]
def rmdir(space, path):
"""Remove a directory."""
Modified: pypy/branch/unicode_filename/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/unicode_filename/pypy/rpython/lltypesystem/rffi.py (original)
+++ pypy/branch/unicode_filename/pypy/rpython/lltypesystem/rffi.py Wed Apr 22 02:05:23 2009
@@ -163,6 +163,17 @@
# 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 str2charp() 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/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/branch/unicode_filename/pypy/rpython/module/ll_os.py (original)
+++ pypy/branch/unicode_filename/pypy/rpython/module/ll_os.py Wed Apr 22 02:05:23 2009
@@ -1238,12 +1238,19 @@
@registering(os.chdir)
def register_os_chdir(self):
- os_chdir = self.llexternal(underscore_on_windows+'chdir', [rffi.CCHARP], rffi.INT)
+ os_chdir = self.llexternal(underscore_on_windows+'chdir',
+ [rffi.CCHARP], rffi.INT)
+ os_wchdir = self.llexternal(underscore_on_windows+'wchdir',
+ [rffi.CWCHARP], rffi.INT)
def chdir_llimpl(path):
- res = rffi.cast(lltype.Signed, os_chdir(path))
+ if isinstance(path, str):
+ res = rffi.cast(lltype.Signed, os_chdir(path))
+ else:
+ res = rffi.cast(lltype.Signed, os_wchdir(path))
if res < 0:
raise OSError(rposix.get_errno(), "os_chdir failed")
+ chdir_llimpl._annspecialcase_ = 'specialize:argtype(0)'
return extdef([str], s_None, llimpl=chdir_llimpl,
export_name="ll_os.ll_os_chdir")
@@ -1256,16 +1263,23 @@
ARG2 = [rffi.MODE_T]
os_mkdir = self.llexternal(underscore_on_windows+'mkdir',
[rffi.CCHARP]+ARG2, rffi.INT)
+ os_wmkdir = self.llexternal(underscore_on_windows+'wmkdir',
+ [rffi.CWCHARP]+ARG2, rffi.INT)
IGNORE_MODE = len(ARG2) == 0
def mkdir_llimpl(pathname, mode):
+ if isinstance(pathname, str):
+ mkdir = os_mkdir
+ else:
+ mkdir = os_wmkdir
if IGNORE_MODE:
- res = os_mkdir(pathname)
+ res = mkdir(pathname)
else:
- res = os_mkdir(pathname, mode)
+ res = mkdir(pathname, mode)
res = rffi.cast(lltype.Signed, res)
if res < 0:
raise OSError(rposix.get_errno(), "os_mkdir failed")
+ mkdir_llimpl._annspecialcase_ = 'specialize:argtype(0)'
return extdef([str, int], s_None, llimpl=mkdir_llimpl,
export_name="ll_os.ll_os_mkdir")
Modified: pypy/branch/unicode_filename/pypy/rpython/module/ll_os_stat.py
==============================================================================
--- pypy/branch/unicode_filename/pypy/rpython/module/ll_os_stat.py (original)
+++ pypy/branch/unicode_filename/pypy/rpython/module/ll_os_stat.py Wed Apr 22 02:05:23 2009
@@ -345,6 +345,16 @@
('ftLastAccessTime', rwin32.FILETIME),
('ftLastWriteTime', rwin32.FILETIME)])
+ WIN32_FIND_DATAW = platform.Struct(
+ 'WIN32_FIND_DATAW',
+ # Only interesting fields
+ [('dwFileAttributes', rwin32.DWORD),
+ ('nFileSizeHigh', rwin32.DWORD),
+ ('nFileSizeLow', rwin32.DWORD),
+ ('ftCreationTime', rwin32.FILETIME),
+ ('ftLastAccessTime', rwin32.FILETIME),
+ ('ftLastWriteTime', rwin32.FILETIME)])
+
globals().update(platform.configure(CConfig))
GET_FILEEX_INFO_LEVELS = rffi.ULONG # an enumeration
@@ -355,6 +365,13 @@
rwin32.BOOL,
calling_conv='win')
+ GetFileAttributesExW = rffi.llexternal(
+ 'GetFileAttributesExW',
+ [rffi.CWCHARP, GET_FILEEX_INFO_LEVELS,
+ lltype.Ptr(WIN32_FILE_ATTRIBUTE_DATA)],
+ rwin32.BOOL,
+ calling_conv='win')
+
GetFileInformationByHandle = rffi.llexternal(
'GetFileInformationByHandle',
[rwin32.HANDLE, lltype.Ptr(BY_HANDLE_FILE_INFORMATION)],
@@ -367,6 +384,12 @@
rwin32.HANDLE,
calling_conv='win')
+ FindFirstFileW = rffi.llexternal(
+ 'FindFirstFileW',
+ [rffi.CWCHARP, lltype.Ptr(WIN32_FIND_DATAW)],
+ rwin32.HANDLE,
+ calling_conv='win')
+
FindClose = rffi.llexternal(
'FindClose',
[rwin32.HANDLE],
@@ -440,9 +463,13 @@
return make_stat_result(result)
- def attributes_from_dir(l_path, data):
- filedata = lltype.malloc(WIN32_FIND_DATA, flavor='raw')
- hFindFile = FindFirstFile(l_path, filedata)
+ def attributes_from_dir(TP, l_path, data):
+ if TP is str:
+ filedata = lltype.malloc(WIN32_FIND_DATA, flavor='raw')
+ hFindFile = FindFirstFile(l_path, filedata)
+ else:
+ filedata = lltype.malloc(WIN32_FIND_DATAW, flavor='raw')
+ hFindFile = FindFirstFileW(l_path, filedata)
if hFindFile == rwin32.INVALID_HANDLE_VALUE:
return 0
FindClose(hFindFile)
@@ -453,23 +480,37 @@
data.c_nFileSizeHigh = filedata.c_nFileSizeHigh
data.c_nFileSizeLow = filedata.c_nFileSizeLow
return 1
+ attributes_from_dir._annspecialcase_ = 'specialize:arg(0)'
def win32_stat_llimpl(path):
+ if isinstance(path, str):
+ TP = str
+ else:
+ TP = unicode
data = lltype.malloc(WIN32_FILE_ATTRIBUTE_DATA, flavor='raw')
try:
- l_path = rffi.str2charp(path)
- res = GetFileAttributesEx(l_path, GetFileExInfoStandard, data)
+ if TP is str:
+ l_path = rffi.str2charp(path)
+ fn = GetFileAttributesEx
+ else:
+ l_path = rffi.unicode2wcharp(path)
+ fn = GetFileAttributesExW
+ res = fn(l_path, GetFileExInfoStandard, data)
errcode = rwin32.GetLastError()
if res == 0:
if errcode == ERROR_SHARING_VIOLATION:
- res = attributes_from_dir(l_path, data)
+ res = attributes_from_dir(TP, l_path, data)
errcode = rwin32.GetLastError()
- rffi.free_charp(l_path)
+ if TP is str:
+ rffi.free_charp(l_path)
+ else:
+ rffi.free_wcharp(l_path)
if res == 0:
raise WindowsError(errcode, "os_stat failed")
return attribute_data_to_stat(data)
finally:
lltype.free(data, flavor='raw')
+ win32_stat_llimpl._annspecialcase_ = 'specialize:argtype(0)'
win32_lstat_llimpl = win32_stat_llimpl
def win32_fstat_llimpl(fd):
More information about the Pypy-commit
mailing list