[Python-checkins] r84956 - in python/branches/py3k: Lib/test/test_os.py Misc/NEWS Modules/posixmodule.c

antoine.pitrou python-checkins at python.org
Tue Sep 21 20:19:07 CEST 2010


Author: antoine.pitrou
Date: Tue Sep 21 20:19:07 2010
New Revision: 84956

Log:
Issue #9908: Fix os.stat() on bytes paths under Windows 7.



Modified:
   python/branches/py3k/Lib/test/test_os.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Modules/posixmodule.c

Modified: python/branches/py3k/Lib/test/test_os.py
==============================================================================
--- python/branches/py3k/Lib/test/test_os.py	(original)
+++ python/branches/py3k/Lib/test/test_os.py	Tue Sep 21 20:19:07 2010
@@ -219,12 +219,12 @@
         os.unlink(self.fname)
         os.rmdir(support.TESTFN)
 
-    def test_stat_attributes(self):
+    def check_stat_attributes(self, fname):
         if not hasattr(os, "stat"):
             return
 
         import stat
-        result = os.stat(self.fname)
+        result = os.stat(fname)
 
         # Make sure direct access works
         self.assertEquals(result[stat.ST_SIZE], 3)
@@ -281,6 +281,15 @@
         except TypeError:
             pass
 
+    def test_stat_attributes(self):
+        self.check_stat_attributes(self.fname)
+
+    def test_stat_attributes_bytes(self):
+        try:
+            fname = self.fname.encode(sys.getfilesystemencoding())
+        except UnicodeEncodeError:
+            self.skipTest("cannot encode %a for the filesystem" % self.fname)
+        self.check_stat_attributes(fname)
 
     def test_statvfs_attributes(self):
         if not hasattr(os, "statvfs"):

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Tue Sep 21 20:19:07 2010
@@ -58,6 +58,8 @@
 Library
 -------
 
+- Issue #9908: Fix os.stat() on bytes paths under Windows 7.
+
 - Issue #2643: msync() is not called anymore when deallocating an open mmap
   object, only munmap().
 

Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c	(original)
+++ python/branches/py3k/Modules/posixmodule.c	Tue Sep 21 20:19:07 2010
@@ -1152,7 +1152,7 @@
         NULL, /* security attributes */
         OPEN_EXISTING,
         /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
-        FILE_FLAG_BACKUP_SEMANTICS,
+        FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
         NULL);
     
     if(hFile == INVALID_HANDLE_VALUE) {
@@ -1175,22 +1175,32 @@
         }
         code = attribute_data_to_stat(&info, result);
     }
-    
-    buf_size = Py_GetFinalPathNameByHandleA(hFile, 0, 0, VOLUME_NAME_DOS);
-    if(!buf_size) return -1;
-    target_path = (char *)malloc((buf_size+1)*sizeof(char));
-    result_length = Py_GetFinalPathNameByHandleA(hFile, target_path,
-                                                 buf_size, VOLUME_NAME_DOS);
-    
-    if(!result_length)
-        return -1;
+    else {
+        /* We have a good handle to the target, use it to determine the target
+           path name (then we'll call lstat on it). */
+        buf_size = Py_GetFinalPathNameByHandleA(hFile, 0, 0, VOLUME_NAME_DOS);
+        if(!buf_size) return -1;
+        /* Due to a slight discrepancy between GetFinalPathNameByHandleA
+           and GetFinalPathNameByHandleW, we must allocate one more byte
+           than reported. */
+        target_path = (char *)malloc((buf_size+2)*sizeof(char));
+        result_length = Py_GetFinalPathNameByHandleA(hFile, target_path,
+                                                     buf_size+1, VOLUME_NAME_DOS);
 
-    if(!CloseHandle(hFile))
-        return -1;
+        if(!result_length) {
+            free(target_path);
+            return -1;
+        }
 
-    target_path[result_length] = 0;
-    code = win32_lstat(target_path, result);
-    free(target_path);
+        if(!CloseHandle(hFile)) {
+            free(target_path);
+            return -1;
+        }
+
+        target_path[result_length] = 0;
+        code = win32_lstat(target_path, result);
+        free(target_path);
+    }
     
     return code;
 }
@@ -1254,11 +1264,15 @@
         result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
                                                 buf_size, VOLUME_NAME_DOS);
         
-        if(!result_length)
+        if(!result_length) {
+            free(target_path);
             return -1;
+        }
 
-        if(!CloseHandle(hFile))
+        if(!CloseHandle(hFile)) {
+            free(target_path);
             return -1;
+        }
 
         target_path[result_length] = 0;
         code = win32_lstat_w(target_path, result);


More information about the Python-checkins mailing list