[pypy-svn] r48393 - in pypy/dist/pypy: module/posix module/posix/test rpython/module rpython/module/test

tismer at codespeak.net tismer at codespeak.net
Thu Nov 8 04:42:53 CET 2007


Author: tismer
Date: Thu Nov  8 04:42:52 2007
New Revision: 48393

Modified:
   pypy/dist/pypy/module/posix/__init__.py
   pypy/dist/pypy/module/posix/interp_posix.py
   pypy/dist/pypy/module/posix/test/test_posix2.py
   pypy/dist/pypy/rpython/module/ll_os.py
   pypy/dist/pypy/rpython/module/test/test_ll_os.py
Log:
added _getfullpathname for windows. including tests, yeah! Especially tested the bad case of "d:stuff" not being propagated through this limited ntpath.py implementation!

Modified: pypy/dist/pypy/module/posix/__init__.py
==============================================================================
--- pypy/dist/pypy/module/posix/__init__.py	(original)
+++ pypy/dist/pypy/module/posix/__init__.py	Thu Nov  8 04:42:52 2007
@@ -88,6 +88,9 @@
         interpleveldefs['geteuid'] = 'interp_posix.geteuid'
     if hasattr(os, 'getgid'):
         interpleveldefs['getgid'] = 'interp_posix.getgid'
+    # not visible via os, inconsistency in nt:
+    if hasattr(posix, '_getfullpathname'):
+        interpleveldefs['_getfullpathname'] = 'interp_posix._getfullpathname'
     
     for name in RegisterOs.w_star:
         if hasattr(os, name):

Modified: pypy/dist/pypy/module/posix/interp_posix.py
==============================================================================
--- pypy/dist/pypy/module/posix/interp_posix.py	(original)
+++ pypy/dist/pypy/module/posix/interp_posix.py	Thu Nov  8 04:42:52 2007
@@ -236,6 +236,17 @@
         raise wrap_oserror(space, e) 
 remove.unwrap_spec = [ObjSpace, str]
 
+def _getfullpathname(space, path):
+    """helper for ntpath.abspath """
+    posix = __import__(os.name) # nt specific
+    try:
+        fullpath = posix._getfullpathname(path)
+    except OSError, e:
+        raise wrap_oserror(space, e) 
+    else: 
+        return space.wrap(fullpath)
+_getfullpathname.unwrap_spec = [ObjSpace, str]
+
 def getcwd(space):
     """Return the current working directory."""
     try:

Modified: pypy/dist/pypy/module/posix/test/test_posix2.py
==============================================================================
--- pypy/dist/pypy/module/posix/test/test_posix2.py	(original)
+++ pypy/dist/pypy/module/posix/test/test_posix2.py	Thu Nov  8 04:42:52 2007
@@ -223,6 +223,16 @@
             stream = os.popen('echo 1')
             assert stream.read() == '1\n'
 
+    if hasattr(__import__(os.name), '_getfullpathname'):
+        def test__getfullpathname(self):
+            # nt specific
+            posix = self.posix
+            import os
+            sysdrv = os.getenv("SystemDrive", "C:")
+            # just see if it does anything
+            path = sysdrv + 'hubber'
+            assert os.sep in posix._getfullpathname(path)
+
     def test_utime(self):
         os = self.posix
         import os.path

Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py	(original)
+++ pypy/dist/pypy/rpython/module/ll_os.py	Thu Nov  8 04:42:52 2007
@@ -519,6 +519,57 @@
                       export_name="ll_os.ll_os_access",
                       oofakeimpl=os_access_oofakeimpl)
 
+    @registering_if(posix, '_getfullpathname')
+    def register_posix__getfullpathname(self):
+        # this nt function is not exposed via os, but needed
+        # to get a correct implementation of os.abspath
+        # XXX why do we ignore WINAPI conventions everywhere?
+        class CConfig:
+            _includes_ = ['Windows.h']
+            MAX_PATH = platform.ConstantInteger('MAX_PATH')
+            DWORD    = platform.SimpleType("DWORD", rffi.ULONG)
+            LPCTSTR  = platform.SimpleType("LPCTSTR", rffi.CCHARP)
+            LPTSTR   = platform.SimpleType("LPTSTR", rffi.CCHARP)
+            LPTSTRP  = platform.SimpleType("LPTSTR*", rffi.CCHARPP)
+
+        config = platform.configure(CConfig)
+        MAX_PATH = config['MAX_PATH']
+        DWORD    = config['DWORD']
+        LPCTSTR  = config['LPCTSTR']
+        LPTSTR   = config['LPTSTR']
+        LPTSTRP  = config['LPTSTRP']
+        # XXX unicode?
+        GetFullPathName = self.llexternal('GetFullPathNameA',
+                         [LPCTSTR, DWORD, LPTSTR, LPTSTRP], DWORD)
+        GetLastError = self.llexternal('GetLastError', [], DWORD)
+        ##DWORD WINAPI GetFullPathName(
+        ##  __in          LPCTSTR lpFileName,
+        ##  __in          DWORD nBufferLength,
+        ##  __out         LPTSTR lpBuffer,
+        ##  __out         LPTSTR* lpFilePart
+        ##);
+
+        def _getfullpathname_llimpl(lpFileName):
+            nBufferLength = MAX_PATH + 1
+            lpBuffer = lltype.malloc(LPTSTR.TO, nBufferLength, flavor='raw')
+            try:
+                res = GetFullPathName(
+                    lpFileName, rffi.cast(DWORD, nBufferLength),
+                    lpBuffer, lltype.nullptr(LPTSTRP.TO))
+                if res == 0:
+                    error = GetLastError()
+                    raise OSError(error, "_getfullpathname failed")
+                # XXX ntpath expects WindowsError :-(
+                result = rffi.charp2str(lpBuffer)
+                return result
+            finally:
+                lltype.free(lpBuffer, flavor='raw')
+
+        return extdef([str],  # a single argument which is a str
+                      str,    # returns a string
+                      "ll_os.posix__getfullpathname",
+                      llimpl=_getfullpathname_llimpl)
+
     @registering(os.getcwd)
     def register_os_getcwd(self):
         os_getcwd = self.llexternal(underscore_on_windows + 'getcwd',

Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/test/test_ll_os.py	(original)
+++ pypy/dist/pypy/rpython/module/test/test_ll_os.py	Thu Nov  8 04:42:52 2007
@@ -31,7 +31,17 @@
     for value in times:
         assert isinstance(value, float)
 
-
+def test__getfullpathname():
+    if os.name != 'nt':
+        py.test.skip('nt specific function')
+    posix = __import__(os.name)
+    sysdrv = os.getenv('SystemDrive', 'C:')
+    stuff = sysdrv + 'stuff'
+    data = getllimpl(posix._getfullpathname)(stuff)
+    assert data == posix._getfullpathname(stuff)
+    # the most intriguing failure of ntpath.py should not repeat, here:
+    assert not data.endswith(stuff)
+    
 def test_getcwd():
     data = getllimpl(os.getcwd)()
     assert data == os.getcwd()



More information about the Pypy-commit mailing list