[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