mirror of
https://github.com/python/cpython.git
synced 2025-11-03 11:23:31 +00:00
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
This commit is contained in:
parent
a0c811e439
commit
afe1706457
2 changed files with 53 additions and 47 deletions
|
|
@ -2051,68 +2051,82 @@ class OSErrorTests(unittest.TestCase):
|
||||||
class Str(str):
|
class Str(str):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.filenames = []
|
self.bytes_filenames = []
|
||||||
|
self.unicode_filenames = []
|
||||||
if support.TESTFN_UNENCODABLE is not None:
|
if support.TESTFN_UNENCODABLE is not None:
|
||||||
decoded = support.TESTFN_UNENCODABLE
|
decoded = support.TESTFN_UNENCODABLE
|
||||||
else:
|
else:
|
||||||
decoded = support.TESTFN
|
decoded = support.TESTFN
|
||||||
self.filenames.append(decoded)
|
self.unicode_filenames.append(decoded)
|
||||||
self.filenames.append(Str(decoded))
|
self.unicode_filenames.append(Str(decoded))
|
||||||
if support.TESTFN_UNDECODABLE is not None:
|
if support.TESTFN_UNDECODABLE is not None:
|
||||||
encoded = support.TESTFN_UNDECODABLE
|
encoded = support.TESTFN_UNDECODABLE
|
||||||
else:
|
else:
|
||||||
encoded = os.fsencode(support.TESTFN)
|
encoded = os.fsencode(support.TESTFN)
|
||||||
self.filenames.append(encoded)
|
self.bytes_filenames.append(encoded)
|
||||||
self.filenames.append(memoryview(encoded))
|
self.bytes_filenames.append(memoryview(encoded))
|
||||||
|
|
||||||
|
self.filenames = self.bytes_filenames + self.unicode_filenames
|
||||||
|
|
||||||
def test_oserror_filename(self):
|
def test_oserror_filename(self):
|
||||||
funcs = [
|
funcs = [
|
||||||
(os.chdir,),
|
(self.filenames, os.chdir,),
|
||||||
(os.chmod, 0o777),
|
(self.filenames, os.chmod, 0o777),
|
||||||
(os.listdir,),
|
(self.filenames, os.listdir,),
|
||||||
(os.lstat,),
|
(self.filenames, os.lstat,),
|
||||||
(os.open, os.O_RDONLY),
|
(self.filenames, os.open, os.O_RDONLY),
|
||||||
(os.rename, "dst"),
|
(self.filenames, os.rmdir,),
|
||||||
(os.replace, "dst"),
|
(self.filenames, os.stat,),
|
||||||
(os.rmdir,),
|
(self.filenames, os.unlink,),
|
||||||
(os.stat,),
|
|
||||||
(os.unlink,),
|
|
||||||
]
|
]
|
||||||
if hasattr(os, "chown"):
|
|
||||||
funcs.append((os.chown, 0, 0))
|
|
||||||
if hasattr(os, "lchown"):
|
|
||||||
funcs.append((os.lchown, 0, 0))
|
|
||||||
if hasattr(os, "truncate"):
|
|
||||||
funcs.append((os.truncate, 0))
|
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
import nt
|
|
||||||
funcs.extend((
|
funcs.extend((
|
||||||
(nt._getfullpathname,),
|
(self.bytes_filenames, os.rename, b"dst"),
|
||||||
(nt._isdir,),
|
(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((self.filenames, os.chown, 0, 0))
|
||||||
|
if hasattr(os, "lchown"):
|
||||||
|
funcs.append((self.filenames, os.lchown, 0, 0))
|
||||||
|
if hasattr(os, "truncate"):
|
||||||
|
funcs.append((self.filenames, os.truncate, 0))
|
||||||
if hasattr(os, "chflags"):
|
if hasattr(os, "chflags"):
|
||||||
funcs.extend((
|
funcs.extend((
|
||||||
(os.chflags, 0),
|
(self.filenames, os.chflags, 0),
|
||||||
(os.lchflags, 0),
|
(self.filenames, os.lchflags, 0),
|
||||||
))
|
))
|
||||||
if hasattr(os, "chroot"):
|
if hasattr(os, "chroot"):
|
||||||
funcs.append((os.chroot,))
|
funcs.append((self.filenames, os.chroot,))
|
||||||
if hasattr(os, "link"):
|
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"):
|
if hasattr(os, "listxattr"):
|
||||||
funcs.extend((
|
funcs.extend((
|
||||||
(os.listxattr,),
|
(self.filenames, os.listxattr,),
|
||||||
(os.getxattr, "user.test"),
|
(self.filenames, os.getxattr, "user.test"),
|
||||||
(os.setxattr, "user.test", b'user'),
|
(self.filenames, os.setxattr, "user.test", b'user'),
|
||||||
(os.removexattr, "user.test"),
|
(self.filenames, os.removexattr, "user.test"),
|
||||||
))
|
))
|
||||||
if hasattr(os, "lchmod"):
|
if hasattr(os, "lchmod"):
|
||||||
funcs.append((os.lchmod, 0o777))
|
funcs.append((self.filenames, os.lchmod, 0o777))
|
||||||
if hasattr(os, "readlink"):
|
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 filenames, func, *func_args in funcs:
|
||||||
for name in self.filenames:
|
for name in filenames:
|
||||||
try:
|
try:
|
||||||
func(name, *func_args)
|
func(name, *func_args)
|
||||||
except OSError as err:
|
except OSError as err:
|
||||||
|
|
|
||||||
|
|
@ -3054,7 +3054,7 @@ posix_link(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return_value = path_error(&dst);
|
return_value = path_error(&src);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
@ -3234,7 +3234,6 @@ posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
if (error == ERROR_FILE_NOT_FOUND)
|
if (error == ERROR_FILE_NOT_FOUND)
|
||||||
goto exit;
|
goto exit;
|
||||||
Py_DECREF(list);
|
Py_DECREF(list);
|
||||||
path.func = "FindFirstFile";
|
|
||||||
list = path_error(&path);
|
list = path_error(&path);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
@ -3263,7 +3262,6 @@ posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
it got to the end of the directory. */
|
it got to the end of the directory. */
|
||||||
if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
|
if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
|
||||||
Py_DECREF(list);
|
Py_DECREF(list);
|
||||||
path.func = "FindNextFile";
|
|
||||||
list = path_error(&path);
|
list = path_error(&path);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
@ -3782,7 +3780,7 @@ internal_rename(PyObject *args, PyObject *kwargs, int is_replace)
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return_value = path_error(&dst);
|
return_value = path_error(&src);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6707,7 +6705,7 @@ posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
return_value = path_error(&dst);
|
return_value = path_error(&src);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -7059,12 +7057,6 @@ posix_open(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (fd == -1) {
|
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);
|
return_value = path_error(&path);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue