[Python-checkins] cpython: Issue #15478: Use source filename in OSError, not destination filename

victor.stinner python-checkins at python.org
Wed Oct 31 22:48:03 CET 2012


http://hg.python.org/cpython/rev/6903f5214e99
changeset:   80139:6903f5214e99
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Wed Oct 31 22:47:43 2012 +0100
summary:
  Issue #15478: Use source filename in OSError, not destination filename

And other fixes for Windows:

 * rename, replace and link require arguments of the same type on Windows
 * readlink only supports unicode filenames on Windows
 * os.open() specifies the filename on OSError

files:
  Lib/test/test_os.py   |  86 ++++++++++++++++++------------
  Modules/posixmodule.c |  14 +---
  2 files changed, 53 insertions(+), 47 deletions(-)


diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -2051,68 +2051,82 @@
         class Str(str):
             pass
 
-        self.filenames = []
+        self.bytes_filenames = []
+        self.unicode_filenames = []
         if support.TESTFN_UNENCODABLE is not None:
             decoded = support.TESTFN_UNENCODABLE
         else:
             decoded = support.TESTFN
-        self.filenames.append(decoded)
-        self.filenames.append(Str(decoded))
+        self.unicode_filenames.append(decoded)
+        self.unicode_filenames.append(Str(decoded))
         if support.TESTFN_UNDECODABLE is not None:
             encoded = support.TESTFN_UNDECODABLE
         else:
             encoded = os.fsencode(support.TESTFN)
-        self.filenames.append(encoded)
-        self.filenames.append(memoryview(encoded))
+        self.bytes_filenames.append(encoded)
+        self.bytes_filenames.append(memoryview(encoded))
+
+        self.filenames = self.bytes_filenames + self.unicode_filenames
 
     def test_oserror_filename(self):
         funcs = [
-            (os.chdir,),
-            (os.chmod, 0o777),
-            (os.listdir,),
-            (os.lstat,),
-            (os.open, os.O_RDONLY),
-            (os.rename, "dst"),
-            (os.replace, "dst"),
-            (os.rmdir,),
-            (os.stat,),
-            (os.unlink,),
+            (self.filenames, os.chdir,),
+            (self.filenames, os.chmod, 0o777),
+            (self.filenames, os.listdir,),
+            (self.filenames, os.lstat,),
+            (self.filenames, os.open, os.O_RDONLY),
+            (self.filenames, os.rmdir,),
+            (self.filenames, os.stat,),
+            (self.filenames, os.unlink,),
         ]
+        if sys.platform == "win32":
+            funcs.extend((
+                (self.bytes_filenames, os.rename, b"dst"),
+                (self.bytes_filenames, os.replace, b"dst"),
+                (self.unicode_filenames, os.rename, "dst"),
+                (self.unicode_filenames, os.replace, "dst"),
+            ))
+        else:
+            funcs.extend((
+                (self.filenames, os.rename, "dst"),
+                (self.filenames, os.replace, "dst"),
+            ))
         if hasattr(os, "chown"):
-            funcs.append((os.chown, 0, 0))
+            funcs.append((self.filenames, os.chown, 0, 0))
         if hasattr(os, "lchown"):
-            funcs.append((os.lchown, 0, 0))
+            funcs.append((self.filenames, os.lchown, 0, 0))
         if hasattr(os, "truncate"):
-            funcs.append((os.truncate, 0))
-        if sys.platform == "win32":
-            import nt
-            funcs.extend((
-                (nt._getfullpathname,),
-                (nt._isdir,),
-            ))
+            funcs.append((self.filenames, os.truncate, 0))
         if hasattr(os, "chflags"):
             funcs.extend((
-                (os.chflags, 0),
-                (os.lchflags, 0),
+                (self.filenames, os.chflags, 0),
+                (self.filenames, os.lchflags, 0),
             ))
         if hasattr(os, "chroot"):
-            funcs.append((os.chroot,))
+            funcs.append((self.filenames, os.chroot,))
         if hasattr(os, "link"):
-            funcs.append((os.link, "dst"))
+            if sys.platform == "win32":
+                funcs.append((self.bytes_filenames, os.link, b"dst"))
+                funcs.append((self.unicode_filenames, os.link, "dst"))
+            else:
+                funcs.append((self.filenames, os.link, "dst"))
         if hasattr(os, "listxattr"):
             funcs.extend((
-                (os.listxattr,),
-                (os.getxattr, "user.test"),
-                (os.setxattr, "user.test", b'user'),
-                (os.removexattr, "user.test"),
+                (self.filenames, os.listxattr,),
+                (self.filenames, os.getxattr, "user.test"),
+                (self.filenames, os.setxattr, "user.test", b'user'),
+                (self.filenames, os.removexattr, "user.test"),
             ))
         if hasattr(os, "lchmod"):
-            funcs.append((os.lchmod, 0o777))
+            funcs.append((self.filenames, os.lchmod, 0o777))
         if hasattr(os, "readlink"):
-            funcs.append((os.readlink,))
+            if sys.platform == "win32":
+                funcs.append((self.unicode_filenames, os.readlink,))
+            else:
+                funcs.append((self.filenames, os.readlink,))
 
-        for func, *func_args in funcs:
-            for name in self.filenames:
+        for filenames, func, *func_args in funcs:
+            for name in filenames:
                 try:
                     func(name, *func_args)
                 except OSError as err:
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -3054,7 +3054,7 @@
     Py_END_ALLOW_THREADS
 
     if (!result) {
-        return_value = path_error(&dst);
+        return_value = path_error(&src);
         goto exit;
     }
 #else
@@ -3234,7 +3234,6 @@
         if (error == ERROR_FILE_NOT_FOUND)
             goto exit;
         Py_DECREF(list);
-        path.func = "FindFirstFile";
         list = path_error(&path);
         goto exit;
     }
@@ -3263,7 +3262,6 @@
            it got to the end of the directory. */
         if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
             Py_DECREF(list);
-            path.func = "FindNextFile";
             list = path_error(&path);
             goto exit;
         }
@@ -3782,7 +3780,7 @@
     Py_END_ALLOW_THREADS
 
     if (!result) {
-        return_value = path_error(&dst);
+        return_value = path_error(&src);
         goto exit;
     }
 
@@ -6707,7 +6705,7 @@
     Py_END_ALLOW_THREADS
 
     if (result) {
-        return_value = path_error(&dst);
+        return_value = path_error(&src);
         goto exit;
     }
 #endif
@@ -7059,12 +7057,6 @@
     Py_END_ALLOW_THREADS
 
     if (fd == -1) {
-#ifdef MS_WINDOWS
-        /* force use of posix_error here for exact backwards compatibility */
-        if (path.wide)
-            return_value = posix_error();
-        else
-#endif
         return_value = path_error(&path);
         goto exit;
     }

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list