[pypy-commit] pypy py3k: move the py3 specific _getfileinformation/_getfinalpathname out of rpython
pjenvey
noreply at buildbot.pypy.org
Tue Oct 14 21:52:55 CEST 2014
Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r73960:906383ab46d1
Date: 2014-10-14 12:51 -0700
http://bitbucket.org/pypy/pypy/changeset/906383ab46d1/
Log: move the py3 specific _getfileinformation/_getfinalpathname out of
rpython
diff --git a/pypy/module/posix/interp_nt.py b/pypy/module/posix/interp_nt.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/posix/interp_nt.py
@@ -0,0 +1,130 @@
+from rpython.rlib import rwin32
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rtyper.module.ll_win32file import make_win32_traits
+from rpython.rtyper.module.support import UnicodeTraits
+from rpython.translator.tool.cbuild import ExternalCompilationInfo
+
+
+# XXX: pypy_GetFinalPathNameByHandle is needed to call the dynamically
+# found GetFinalPathNameByHandle function with a non-standard calling
+# convention. currently FuncType pointer calls w/ non-standard calling
+# conventions don't work after translation
+separate_module_source = """\
+DWORD
+pypy_GetFinalPathNameByHandle(FARPROC address, HANDLE hFile,
+ LPTSTR lpszFilePath, DWORD cchFilePath,
+ DWORD dwFlags) {
+ DWORD (WINAPI *func)(HANDLE, LPTSTR, DWORD, DWORD);
+ *(FARPROC*)&func = address;
+ return func(hFile, lpszFilePath, cchFilePath, dwFlags);
+}
+"""
+eci = ExternalCompilationInfo(
+ includes=['windows.h'],
+ separate_module_sources=[separate_module_source],
+ export_symbols=['pypy_GetFinalPathNameByHandle']
+ )
+pypy_GetFinalPathNameByHandle = rffi.llexternal(
+ 'pypy_GetFinalPathNameByHandle',
+ [rffi.VOIDP, rwin32.HANDLE, rffi.CWCHARP, rwin32.DWORD, rwin32.DWORD],
+ rwin32.DWORD, compilation_info=eci)
+
+
+# plain NotImplementedError is invalid RPython
+class LLNotImplemented(NotImplementedError):
+
+ def __init__(self, msg):
+ self.msg = msg
+
+
+def make_traits(traits):
+ win32traits = make_win32_traits(traits)
+
+ class NTTraits(win32traits):
+
+ GetFinalPathNameByHandle_HANDLE = lltype.nullptr(rffi.VOIDP.TO)
+
+ def check_GetFinalPathNameByHandle(self):
+ if (self.GetFinalPathNameByHandle_HANDLE !=
+ lltype.nullptr(rffi.VOIDP.TO)):
+ return True
+
+ from rpython.rlib.rdynload import GetModuleHandle, dlsym
+ hKernel32 = GetModuleHandle("KERNEL32")
+ try:
+ func = dlsym(hKernel32, 'GetFinalPathNameByHandleW')
+ except KeyError:
+ return False
+
+ self.GetFinalPathNameByHandle_HANDLE = func
+ return True
+
+ def GetFinalPathNameByHandle(self, *args):
+ assert (self.GetFinalPathNameByHandle_HANDLE !=
+ lltype.nullptr(rffi.VOIDP.TO))
+ return pypy_GetFinalPathNameByHandle(
+ self.GetFinalPathNameByHandle_HANDLE, *args)
+
+ return NTTraits()
+
+
+def make__getfileinformation_impl(traits):
+ win32traits = make_traits(traits)
+
+ def _getfileinformation_llimpl(fd):
+ hFile = rwin32.get_osfhandle(fd)
+ with lltype.scoped_alloc(
+ win32traits.BY_HANDLE_FILE_INFORMATION) as info:
+ if win32traits.GetFileInformationByHandle(hFile, info) == 0:
+ raise rwin32.lastWindowsError("_getfileinformation")
+ return (rffi.cast(lltype.Signed, info.c_dwVolumeSerialNumber),
+ rffi.cast(lltype.Signed, info.c_nFileIndexHigh),
+ rffi.cast(lltype.Signed, info.c_nFileIndexLow))
+
+ return _getfileinformation_llimpl
+
+
+def make__getfinalpathname_impl(traits):
+ assert traits.str is unicode, 'Currently only handles unicode paths'
+ win32traits = make_traits(traits)
+
+ def _getfinalpathname_llimpl(path):
+ if not win32traits.check_GetFinalPathNameByHandle():
+ raise LLNotImplemented("GetFinalPathNameByHandle not available on "
+ "this platform")
+
+ hFile = win32traits.CreateFile(path, 0, 0, None,
+ win32traits.OPEN_EXISTING,
+ win32traits.FILE_FLAG_BACKUP_SEMANTICS,
+ rwin32.NULL_HANDLE)
+ if hFile == rwin32.INVALID_HANDLE_VALUE:
+ raise rwin32.lastWindowsError("CreateFile")
+
+ VOLUME_NAME_DOS = rffi.cast(rwin32.DWORD, win32traits.VOLUME_NAME_DOS)
+ try:
+ usize = win32traits.GetFinalPathNameByHandle(
+ hFile,
+ lltype.nullptr(traits.CCHARP.TO),
+ rffi.cast(rwin32.DWORD, 0),
+ VOLUME_NAME_DOS)
+ if usize == 0:
+ raise rwin32.lastWindowsError("GetFinalPathNameByHandle")
+
+ size = rffi.cast(lltype.Signed, usize)
+ with rffi.scoped_alloc_unicodebuffer(size + 1) as buf:
+ result = win32traits.GetFinalPathNameByHandle(
+ hFile,
+ buf.raw,
+ usize,
+ VOLUME_NAME_DOS)
+ if result == 0:
+ raise rwin32.lastWindowsError("GetFinalPathNameByHandle")
+ return buf.str(rffi.cast(lltype.Signed, result))
+ finally:
+ rwin32.CloseHandle(hFile)
+
+ return _getfinalpathname_llimpl
+
+
+_getfileinformation = make__getfileinformation_impl(UnicodeTraits())
+_getfinalpathname = make__getfinalpathname_impl(UnicodeTraits())
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
@@ -5,7 +5,8 @@
from rpython.rlib.objectmodel import specialize
from rpython.rlib.rarithmetic import r_longlong
from rpython.rlib.unroll import unrolling_iterable
-from rpython.rtyper.module import ll_os, ll_os_stat
+from rpython.rtyper.module import ll_os_stat
+from rpython.rtyper.module.ll_os import RegisterOs
from pypy.interpreter.gateway import unwrap_spec, WrappedDefault
from pypy.interpreter.error import OperationError, wrap_oserror, wrap_oserror2
@@ -1204,7 +1205,7 @@
raise wrap_oserror(space, e)
def declare_new_w_star(name):
- if name in ll_os.RegisterOs.w_star_returning_int:
+ if name in RegisterOs.w_star_returning_int:
@unwrap_spec(status=c_int)
def WSTAR(space, status):
return space.wrap(getattr(os, name)(status))
@@ -1216,7 +1217,7 @@
WSTAR.func_name = name
return WSTAR
-for name in ll_os.RegisterOs.w_star:
+for name in RegisterOs.w_star:
if hasattr(os, name):
func = declare_new_w_star(name)
globals()[name] = func
@@ -1384,10 +1385,12 @@
return space.w_None
if _WIN32:
+ from pypy.module.posix import interp_nt as nt
+
@unwrap_spec(fd=c_int)
def _getfileinformation(space, fd):
try:
- info = ll_os._getfileinformation(fd)
+ info = nt._getfileinformation(fd)
except OSError as e:
raise wrap_oserror(space, e)
return space.newtuple([space.wrap(info[0]),
@@ -1397,8 +1400,8 @@
def _getfinalpathname(space, w_path):
path = space.unicode_w(w_path)
try:
- result = ll_os._getfinalpathname(path)
- except ll_os.LLNotImplemented as e:
+ result = nt._getfinalpathname(path)
+ except nt.LLNotImplemented as e:
raise OperationError(space.w_NotImplementedError,
space.wrap(e.msg))
except OSError as e:
diff --git a/pypy/module/posix/test/test_nt.py b/pypy/module/posix/test/test_nt.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/posix/test/test_nt.py
@@ -0,0 +1,27 @@
+import os
+import sys
+
+import py
+
+if not sys.platform.startswith('win'):
+ py.test.skip("requires Windows")
+
+from pypy.module.posix import interp_nt as nt
+
+
+def test__getfileinformation():
+ with open(__file__) as fp:
+ stat = os.fstat(fp.fileno())
+ info = nt._getfileinformation(fp.fileno())
+ serial, high, low = info
+ assert type(serial) in (int, long)
+ assert (high << 32) + low == stat.st_ino
+
+
+def test__getfinalpathname():
+ path = __file__.decode('mbcs')
+ try:
+ result = nt._getfinalpathname(path)
+ except nt.LLNotImplemented:
+ py.test.skip("_getfinalpathname not supported on this platform")
+ assert os.path.exists(result)
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
@@ -105,12 +105,6 @@
_CYGWIN = sys.platform == 'cygwin'
-# plain NotImplementedError is invalid RPython
-class LLNotImplemented(NotImplementedError):
-
- def __init__(self, msg):
- self.msg = msg
-
class CConfig:
"""
Definitions for platform integration.
@@ -1969,12 +1963,10 @@
return OsEnvironController()
# ____________________________________________________________
-# Support for the WindowsError exception and misc functions
+# Support for the WindowsError exception
if sys.platform == 'win32':
from rpython.rlib import rwin32
- from rpython.rtyper.module.ll_win32file import (
- make__getfileinformation_impl, make__getfinalpathname_impl)
class RegisterFormatError(BaseLazyRegistering):
def __init__(self):
@@ -1985,6 +1977,3 @@
return extdef([lltype.Signed], str,
"rwin32_FormatError",
llimpl=rwin32.llimpl_FormatError)
-
- _getfileinformation = make__getfileinformation_impl(UnicodeTraits())
- _getfinalpathname = make__getfinalpathname_impl(UnicodeTraits())
diff --git a/rpython/rtyper/module/ll_win32file.py b/rpython/rtyper/module/ll_win32file.py
--- a/rpython/rtyper/module/ll_win32file.py
+++ b/rpython/rtyper/module/ll_win32file.py
@@ -10,17 +10,6 @@
from rpython.tool.sourcetools import func_renamer
from rpython.rlib.objectmodel import specialize
-separate_module_source = """\
-DWORD
-pypy_GetFinalPathNameByHandle(FARPROC address, HANDLE hFile,
- LPTSTR lpszFilePath, DWORD cchFilePath,
- DWORD dwFlags) {
- DWORD (WINAPI *func)(HANDLE, LPTSTR, DWORD, DWORD);
- *(FARPROC*)&func = address;
- return func(hFile, lpszFilePath, cchFilePath, dwFlags);
-}
-"""
-
def make_win32_traits(traits):
from rpython.rlib import rwin32
@@ -32,8 +21,6 @@
class CConfig:
_compilation_info_ = ExternalCompilationInfo(
includes = ['windows.h', 'winbase.h', 'sys/stat.h'],
- separate_module_sources=[separate_module_source],
- export_symbols=['pypy_GetFinalPathNameByHandle']
)
WIN32_FIND_DATA = platform.Struct(
'struct _WIN32_FIND_DATA' + suffix,
@@ -205,34 +192,7 @@
[traits.CCHARP, traits.CCHARP],
rwin32.BOOL)
- GetFinalPathNameByHandle_HANDLE = lltype.nullptr(rffi.VOIDP.TO)
- pypy_GetFinalPathNameByHandle = staticmethod(rffi.llexternal(
- 'pypy_GetFinalPathNameByHandle',
- [rffi.VOIDP, rwin32.HANDLE, rffi.CWCHARP, rwin32.DWORD, rwin32.DWORD],
- rwin32.DWORD, compilation_info=CConfig._compilation_info_))
-
- def check_GetFinalPathNameByHandle(self):
- if (self.GetFinalPathNameByHandle_HANDLE !=
- lltype.nullptr(rffi.VOIDP.TO)):
- return True
-
- from rpython.rlib.rdynload import GetModuleHandle, dlsym
- hKernel32 = GetModuleHandle("KERNEL32")
- try:
- func = dlsym(hKernel32, 'GetFinalPathNameByHandle' + suffix)
- except KeyError:
- return False
-
- self.GetFinalPathNameByHandle_HANDLE = func
- return True
-
- def GetFinalPathNameByHandle(self, *args):
- assert (self.GetFinalPathNameByHandle_HANDLE !=
- lltype.nullptr(rffi.VOIDP.TO))
- return self.pypy_GetFinalPathNameByHandle(
- self.GetFinalPathNameByHandle_HANDLE, *args)
-
- return Win32Traits()
+ return Win32Traits
#_______________________________________________________________
# listdir
@@ -451,68 +411,3 @@
lltype.free(mtime, flavor='raw')
return os_utime_llimpl
-
-#_______________________________________________________________
-# _getfileinformation (py3)
-
-def make__getfileinformation_impl(traits):
- from rpython.rlib import rwin32
- win32traits = make_win32_traits(traits)
-
- def _getfileinformation_llimpl(fd):
- hFile = rwin32.get_osfhandle(fd)
- with lltype.scoped_alloc(
- win32traits.BY_HANDLE_FILE_INFORMATION) as info:
- if win32traits.GetFileInformationByHandle(hFile, info) == 0:
- raise rwin32.lastWindowsError("_getfileinformation")
- return (rffi.cast(lltype.Signed, info.c_dwVolumeSerialNumber),
- rffi.cast(lltype.Signed, info.c_nFileIndexHigh),
- rffi.cast(lltype.Signed, info.c_nFileIndexLow))
-
- return _getfileinformation_llimpl
-
-#_______________________________________________________________
-# _getfinalpathname (py3)
-
-def make__getfinalpathname_impl(traits):
- from rpython.rlib import rwin32
- from rpython.rtyper.module.ll_os import LLNotImplemented
- assert traits.str is unicode, 'Currently only handles unicode paths'
- win32traits = make_win32_traits(traits)
-
- def _getfinalpathname_llimpl(path):
- if not win32traits.check_GetFinalPathNameByHandle():
- raise LLNotImplemented("GetFinalPathNameByHandle not available on "
- "this platform")
-
- hFile = win32traits.CreateFile(path, 0, 0, None,
- win32traits.OPEN_EXISTING,
- win32traits.FILE_FLAG_BACKUP_SEMANTICS,
- rwin32.NULL_HANDLE)
- if hFile == rwin32.INVALID_HANDLE_VALUE:
- raise rwin32.lastWindowsError("CreateFile")
-
- VOLUME_NAME_DOS = rffi.cast(rwin32.DWORD, win32traits.VOLUME_NAME_DOS)
- try:
- usize = win32traits.GetFinalPathNameByHandle(
- hFile,
- lltype.nullptr(traits.CCHARP.TO),
- rffi.cast(rwin32.DWORD, 0),
- VOLUME_NAME_DOS)
- if usize == 0:
- raise rwin32.lastWindowsError("GetFinalPathNameByHandle")
-
- size = rffi.cast(lltype.Signed, usize)
- with rffi.scoped_alloc_unicodebuffer(size + 1) as buf:
- result = win32traits.GetFinalPathNameByHandle(
- hFile,
- buf.raw,
- usize,
- VOLUME_NAME_DOS)
- if result == 0:
- raise rwin32.lastWindowsError("GetFinalPathNameByHandle")
- return buf.str(rffi.cast(lltype.Signed, result))
- finally:
- rwin32.CloseHandle(hFile)
-
- return _getfinalpathname_llimpl
diff --git a/rpython/rtyper/module/test/test_ll_win32file.py b/rpython/rtyper/module/test/test_ll_win32file.py
deleted file mode 100644
--- a/rpython/rtyper/module/test/test_ll_win32file.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import os
-
-import py
-
-from rpython.rtyper.module import ll_os
-
-if not ll_os._WIN32:
- py.test.skip("requires Windows")
-
-
-def test__getfileinformation():
- with open(__file__) as fp:
- stat = os.fstat(fp.fileno())
- info = ll_os._getfileinformation(fp.fileno())
- serial, high, low = info
- assert type(serial) in (int, long)
- assert (high << 32) + low == stat.st_ino
-
-
-def test__getfinalpathname():
- path = __file__.decode('mbcs')
- try:
- result = ll_os._getfinalpathname(path)
- except ll_os.LLNotImplemented:
- py.test.skip("_getfinalpathname not supported on this platform")
- assert os.path.exists(result)
More information about the pypy-commit
mailing list