[pypy-svn] r76189 - in pypy/branch/unicode_filename-2/pypy: module/posix rlib rlib/test rpython/module
afa at codespeak.net
afa at codespeak.net
Tue Jul 13 18:41:22 CEST 2010
Author: afa
Date: Tue Jul 13 18:41:20 2010
New Revision: 76189
Modified:
pypy/branch/unicode_filename-2/pypy/module/posix/interp_posix.py
pypy/branch/unicode_filename-2/pypy/rlib/rposix.py
pypy/branch/unicode_filename-2/pypy/rlib/rwin32.py
pypy/branch/unicode_filename-2/pypy/rlib/test/test_rposix.py
pypy/branch/unicode_filename-2/pypy/rpython/module/ll_os.py
Log:
Implement win32 unicode version of os.listdir()
Modified: pypy/branch/unicode_filename-2/pypy/module/posix/interp_posix.py
==============================================================================
--- pypy/branch/unicode_filename-2/pypy/module/posix/interp_posix.py (original)
+++ pypy/branch/unicode_filename-2/pypy/module/posix/interp_posix.py Tue Jul 13 18:41:20 2010
@@ -434,7 +434,7 @@
unsetenv.unwrap_spec = [ObjSpace, str]
-def listdir(space, dirname):
+def listdir(space, w_dirname):
"""Return a list containing the names of the entries in the directory.
\tpath: path of directory to list
@@ -442,12 +442,18 @@
The list is in arbitrary order. It does not include the special
entries '.' and '..' even if they are present in the directory."""
try:
- result = os.listdir(dirname)
+ if space.isinstance_w(w_dirname, space.w_unicode):
+ dirname = FileEncoder(space, w_dirname)
+ result = rposix.listdir(dirname)
+ result_w = [space.wrap(s) for s in result]
+ else:
+ dirname = space.str_w(w_dirname)
+ result = rposix.listdir(dirname)
+ result_w = [space.wrap(s) for s in result]
except OSError, e:
- raise wrap_oserror(space, e, dirname)
- result_w = [space.wrap(s) for s in result]
+ raise wrap_oserror2(space, e, w_dirname)
return space.newlist(result_w)
-listdir.unwrap_spec = [ObjSpace, str]
+listdir.unwrap_spec = [ObjSpace, W_Root]
def pipe(space):
"Create a pipe. Returns (read_end, write_end)."
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 Tue Jul 13 18:41:20 2010
@@ -74,3 +74,10 @@
return os.unlink(path)
else:
return os.unlink(path.encode())
+
+ at specialize.argtype(0)
+def listdir(dirname):
+ if isinstance(dirname, str):
+ return os.listdir(dirname)
+ else:
+ return os.listdir(dirname.encode())
Modified: pypy/branch/unicode_filename-2/pypy/rlib/rwin32.py
==============================================================================
--- pypy/branch/unicode_filename-2/pypy/rlib/rwin32.py (original)
+++ pypy/branch/unicode_filename-2/pypy/rlib/rwin32.py Tue Jul 13 18:41:20 2010
@@ -31,6 +31,7 @@
DWORD = rffi_platform.SimpleType("DWORD", rffi.UINT)
BOOL = rffi_platform.SimpleType("BOOL", rffi.LONG)
BYTE = rffi_platform.SimpleType("BYTE", rffi.UCHAR)
+ WCHAR = rffi_platform.SimpleType("WCHAR", rffi.UCHAR)
INT = rffi_platform.SimpleType("INT", rffi.INT)
LONG = rffi_platform.SimpleType("LONG", rffi.LONG)
PLONG = rffi_platform.SimpleType("PLONG", rffi.LONGP)
@@ -38,6 +39,7 @@
LPCVOID = rffi_platform.SimpleType("LPCVOID", rffi.VOIDP)
LPSTR = rffi_platform.SimpleType("LPSTR", rffi.CCHARP)
LPCSTR = rffi_platform.SimpleType("LPCSTR", rffi.CCHARP)
+ LPCWSTR = rffi_platform.SimpleType("LPCWSTR", rffi.CWCHARP)
LPDWORD = rffi_platform.SimpleType("LPDWORD", rffi.INTP)
SIZE_T = rffi_platform.SimpleType("SIZE_T", rffi.SIZE_T)
ULONG_PTR = rffi_platform.SimpleType("ULONG_PTR", rffi.ULONG)
@@ -87,6 +89,10 @@
GetLastError = winexternal('GetLastError', [], DWORD)
SetLastError = winexternal('SetLastError', [DWORD], lltype.Void)
+ # In tests, the first call to GetLastError is always wrong, because error
+ # is hidden by operations in ll2ctypes. Call it now.
+ GetLastError()
+
LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], rffi.VOIDP)
GetProcAddress = winexternal('GetProcAddress',
[rffi.VOIDP, rffi.CCHARP],
Modified: pypy/branch/unicode_filename-2/pypy/rlib/test/test_rposix.py
==============================================================================
--- pypy/branch/unicode_filename-2/pypy/rlib/test/test_rposix.py (original)
+++ pypy/branch/unicode_filename-2/pypy/rlib/test/test_rposix.py Tue Jul 13 18:41:20 2010
@@ -1,11 +1,23 @@
from pypy.rpython.test.test_llinterp import interpret
from pypy.tool.udir import udir
from pypy.rlib import rposix
-import os
+import os, sys
def ll_to_string(s):
return ''.join(s.chars)
+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")
+
+ def gettext(self):
+ return self.unistr
+
class TestPosixUnicode:
def setup_method(self, method):
self.ufilename = (unicode(udir.join('test_open')) +
@@ -14,18 +26,6 @@
f.write("test")
f.close()
- 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")
-
- def gettext(self):
- return self.unistr
-
self.path = UnicodeWithEncoding(self.ufilename)
def test_access(self):
@@ -54,3 +54,11 @@
interpret(f, [])
assert not os.path.exists(self.ufilename)
+
+ def test_listdir(self):
+ udir = UnicodeWithEncoding(os.path.dirname(self.ufilename))
+ def f():
+ return u', '.join(rposix.listdir(udir))
+
+ result = interpret(f, [])
+ assert os.path.basename(self.ufilename) in ll_to_string(result)
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 Tue Jul 13 18:41:20 2010
@@ -1035,10 +1035,10 @@
ERROR_NO_MORE_FILES = config['ERROR_NO_MORE_FILES']
LPWIN32_FIND_DATA = lltype.Ptr(WIN32_FIND_DATA)
- FindFirstFile = self.llexternal('FindFirstFile',
+ FindFirstFile = self.llexternal('FindFirstFileA',
[rwin32.LPCSTR, LPWIN32_FIND_DATA],
rwin32.HANDLE)
- FindNextFile = self.llexternal('FindNextFile',
+ FindNextFile = self.llexternal('FindNextFileA',
[rwin32.HANDLE, LPWIN32_FIND_DATA],
rwin32.BOOL)
FindClose = self.llexternal('FindClose',
@@ -1122,6 +1122,73 @@
"ll_os.ll_os_listdir",
llimpl=os_listdir_llimpl)
+ @registering_unicode_version(os.listdir, 1, [0], sys.platform=='win32')
+ def register_os_listdir_unicode(self):
+ from pypy.rlib import rwin32
+ class CConfig:
+ _compilation_info_ = ExternalCompilationInfo(
+ includes = ['windows.h']
+ )
+ WIN32_FIND_DATA = platform.Struct('struct _WIN32_FIND_DATAW',
+ [('cFileName', lltype.FixedSizeArray(rwin32.WCHAR, 250))])
+ ERROR_FILE_NOT_FOUND = platform.ConstantInteger(
+ 'ERROR_FILE_NOT_FOUND')
+ ERROR_NO_MORE_FILES = platform.ConstantInteger(
+ 'ERROR_NO_MORE_FILES')
+
+ config = platform.configure(CConfig)
+ WIN32_FIND_DATA = config['WIN32_FIND_DATA']
+ ERROR_FILE_NOT_FOUND = config['ERROR_FILE_NOT_FOUND']
+ ERROR_NO_MORE_FILES = config['ERROR_NO_MORE_FILES']
+ LPWIN32_FIND_DATA = lltype.Ptr(WIN32_FIND_DATA)
+
+ FindFirstFile = self.llexternal('FindFirstFileW',
+ [rwin32.LPCWSTR, LPWIN32_FIND_DATA],
+ rwin32.HANDLE)
+ FindNextFile = self.llexternal('FindNextFileW',
+ [rwin32.HANDLE, LPWIN32_FIND_DATA],
+ rwin32.BOOL)
+ FindClose = self.llexternal('FindClose',
+ [rwin32.HANDLE],
+ rwin32.BOOL)
+
+ def os_listdir_llimpl(path):
+ if path and path[-1] not in (u'/', u'\\', u':'):
+ path += u'/'
+ path += u'*.*'
+ filedata = lltype.malloc(WIN32_FIND_DATA, flavor='raw')
+ try:
+ result = []
+ hFindFile = FindFirstFile(path, filedata)
+ if hFindFile == rwin32.INVALID_HANDLE_VALUE:
+ error = rwin32.GetLastError()
+ if error == ERROR_FILE_NOT_FOUND:
+ return result
+ else:
+ raise WindowsError(error, "FindFirstFile failed")
+ while True:
+ name = rffi.wcharp2unicode(rffi.cast(rffi.CWCHARP,
+ filedata.c_cFileName))
+ if name != u"." and name != u"..": # skip these
+ result.append(name)
+ if not FindNextFile(hFindFile, filedata):
+ break
+ # FindNextFile sets error to ERROR_NO_MORE_FILES if
+ # it got to the end of the directory
+ error = rwin32.GetLastError()
+ FindClose(hFindFile)
+ if error == ERROR_NO_MORE_FILES:
+ return result
+ else:
+ raise WindowsError(error, "FindNextFile failed")
+ finally:
+ lltype.free(filedata, flavor='raw')
+
+ return extdef([unicode], # a single argument which is a unicode
+ [unicode], # returns a list of unicodes
+ "ll_os.ll_os_wlistdir",
+ llimpl=os_listdir_llimpl)
+
@registering(os.pipe)
def register_os_pipe(self):
# we need a different approach on Windows and on Posix
More information about the Pypy-commit
mailing list