diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2011-11-15 21:27:43 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2011-11-15 21:27:43 (GMT) |
commit | 8ab440e4771c4118e874cbb05b5f8f09a4408f49 (patch) | |
tree | 889e37790b5d834a14a3b58cfb8f4c3e6fbc88eb | |
parent | 8ad982cccf439419937bf2acf111f7ee197c4181 (diff) | |
parent | 1ab6c2d2c2b6c78e492491542007edfb880889f0 (diff) | |
download | cpython-8ab440e4771c4118e874cbb05b5f8f09a4408f49.zip cpython-8ab440e4771c4118e874cbb05b5f8f09a4408f49.tar.gz cpython-8ab440e4771c4118e874cbb05b5f8f09a4408f49.tar.bz2 |
Merge
-rw-r--r-- | Doc/whatsnew/3.3.rst | 4 | ||||
-rw-r--r-- | Lib/test/test_genericpath.py | 21 | ||||
-rw-r--r-- | Lib/test/test_ntpath.py | 7 | ||||
-rw-r--r-- | Lib/test/test_os.py | 44 | ||||
-rw-r--r-- | Lib/test/test_pep277.py | 9 | ||||
-rw-r--r-- | Lib/test/test_posixpath.py | 12 | ||||
-rw-r--r-- | Misc/NEWS | 4 | ||||
-rw-r--r-- | Modules/posixmodule.c | 328 |
8 files changed, 262 insertions, 167 deletions
diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 7e877fc..7be122d 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -573,6 +573,10 @@ Porting Python code with sys.platform.startswith('linux'), or directly sys.platform == 'linux' if you don't need to support older Python versions. +* Issue #13374: The Windows bytes API has been deprecated in the :mod:`os` + module. Use Unicode filenames instead of bytes filenames to not depend on the + ANSI code page anymore and to support any filename. + Porting C code -------------- diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 50638a1..b618d45 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -2,11 +2,12 @@ Tests common to genericpath, macpath, ntpath and posixpath """ -import unittest -from test import support -import os import genericpath +import os import sys +import unittest +import warnings +from test import support def safe_rmdir(dirname): @@ -258,7 +259,9 @@ class CommonTest(GenericTest): def test_abspath(self): self.assertIn("foo", self.pathmodule.abspath("foo")) - self.assertIn(b"foo", self.pathmodule.abspath(b"foo")) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + self.assertIn(b"foo", self.pathmodule.abspath(b"foo")) # Abspath returns bytes when the arg is bytes for path in (b'', b'foo', b'f\xf2\xf2', b'/foo', b'C:\\'): @@ -266,7 +269,9 @@ class CommonTest(GenericTest): def test_realpath(self): self.assertIn("foo", self.pathmodule.realpath("foo")) - self.assertIn(b"foo", self.pathmodule.realpath(b"foo")) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + self.assertIn(b"foo", self.pathmodule.realpath(b"foo")) def test_normpath_issue5827(self): # Make sure normpath preserves unicode @@ -296,8 +301,10 @@ class CommonTest(GenericTest): "Mac OS X denies the creation of a directory with an invalid utf8 name") def test_nonascii_abspath(self): # Test non-ASCII, non-UTF8 bytes in the path. - with support.temp_cwd(b'\xe7w\xf0'): - self.test_abspath() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + with support.temp_cwd(b'\xe7w\xf0'): + self.test_abspath() def test_main(): diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 6464950..2c9dab9 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -1,10 +1,11 @@ import ntpath import os import sys +import unittest +import warnings from test.support import TestFailed from test import support, test_genericpath from tempfile import TemporaryFile -import unittest def tester(fn, wantResult): @@ -21,7 +22,9 @@ def tester(fn, wantResult): fn = fn.replace('["', '[b"') fn = fn.replace(", '", ", b'") fn = fn.replace(', "', ', b"') - gotResult = eval(fn) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + gotResult = eval(fn) if isinstance(wantResult, str): wantResult = wantResult.encode('ascii') elif isinstance(wantResult, tuple): diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index da143cf..ec2877e 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -213,7 +213,9 @@ class StatAttributeTests(unittest.TestCase): fname = self.fname.encode(sys.getfilesystemencoding()) except UnicodeEncodeError: self.skipTest("cannot encode %a for the filesystem" % self.fname) - self.check_stat_attributes(fname) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + self.check_stat_attributes(fname) def test_statvfs_attributes(self): if not hasattr(os, "statvfs"): @@ -838,7 +840,9 @@ class LinkTests(unittest.TestCase): with open(file1, "w") as f1: f1.write("test") - os.link(file1, file2) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + os.link(file1, file2) with open(file1, "r") as f1, open(file2, "r") as f2: self.assertTrue(os.path.sameopenfile(f1.fileno(), f2.fileno())) @@ -1160,8 +1164,10 @@ class Win32SymlinkTests(unittest.TestCase): self.assertNotEqual(os.lstat(link), os.stat(link)) bytes_link = os.fsencode(link) - self.assertEqual(os.stat(bytes_link), os.stat(target)) - self.assertNotEqual(os.lstat(bytes_link), os.stat(bytes_link)) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + self.assertEqual(os.stat(bytes_link), os.stat(target)) + self.assertNotEqual(os.lstat(bytes_link), os.stat(bytes_link)) def test_12084(self): level1 = os.path.abspath(support.TESTFN) @@ -1619,6 +1625,35 @@ class ExtendedAttributeTests(unittest.TestCase): self._check_xattrs(getxattr, setxattr, removexattr, listxattr) +@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") +class Win32DeprecatedBytesAPI(unittest.TestCase): + def test_deprecated(self): + import nt + filename = os.fsencode(support.TESTFN) + with warnings.catch_warnings(): + warnings.simplefilter("error", DeprecationWarning) + for func, *args in ( + (nt._getfullpathname, filename), + (nt._isdir, filename), + (os.access, filename, os.R_OK), + (os.chdir, filename), + (os.chmod, filename, 0o777), + (os.link, filename, filename), + (os.listdir, filename), + (os.lstat, filename), + (os.mkdir, filename), + (os.open, filename, os.O_RDONLY), + (os.rename, filename, filename), + (os.rmdir, filename), + (os.startfile, filename), + (os.stat, filename), + (os.symlink, filename, filename), + (os.unlink, filename), + (os.utime, filename), + ): + self.assertRaises(DeprecationWarning, func, *args) + + @support.reap_threads def test_main(): support.run_unittest( @@ -1643,6 +1678,7 @@ def test_main(): TestSendfile, ProgramPriorityTests, ExtendedAttributeTests, + Win32DeprecatedBytesAPI, ) if __name__ == "__main__": diff --git a/Lib/test/test_pep277.py b/Lib/test/test_pep277.py index a1a4791..4b16cbb 100644 --- a/Lib/test/test_pep277.py +++ b/Lib/test/test_pep277.py @@ -1,6 +1,9 @@ # Test the Unicode versions of normal file functions # open, os.open, os.stat. os.listdir, os.rename, os.remove, os.mkdir, os.chdir, os.rmdir -import sys, os, unittest +import os +import sys +import unittest +import warnings from unicodedata import normalize from test import support @@ -155,7 +158,9 @@ class UnicodeFileTests(unittest.TestCase): @unittest.skipIf(sys.platform == 'darwin', 'irrelevant test on Mac OS X') def test_listdir(self): sf0 = set(self.files) - f1 = os.listdir(support.TESTFN.encode(sys.getfilesystemencoding())) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + f1 = os.listdir(support.TESTFN.encode(sys.getfilesystemencoding())) f2 = os.listdir(support.TESTFN) sf2 = set(os.path.join(support.TESTFN, f) for f in f2) self.assertEqual(sf0, sf2, "%a != %a" % (sf0, sf2)) diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index bb4559c..709ef04 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -1,10 +1,10 @@ -import unittest -from test import support, test_genericpath - -import posixpath import os +import posixpath import sys +import unittest +import warnings from posixpath import realpath, abspath, dirname, basename +from test import support, test_genericpath try: import posix @@ -231,7 +231,9 @@ class PosixPathTest(unittest.TestCase): def test_ismount(self): self.assertIs(posixpath.ismount("/"), True) - self.assertIs(posixpath.ismount(b"/"), True) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + self.assertIs(posixpath.ismount(b"/"), True) def test_ismount_non_existent(self): # Non-existent mountpoint. @@ -374,6 +374,10 @@ Core and Builtins Library ------- +- Issue #13374: The Windows bytes API has been deprecated in the os module. Use + Unicode filenames instead of bytes filenames to not depend on the ANSI code + page anymore and to support any filename. + - Issue #13297: Use bytes type to send and receive binary data through XMLRPC. - Issue #6397: Support "/dev/poll" polling objects in select module, diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 26fc25f..9012e39 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -546,6 +546,34 @@ win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) return TRUE; } + +static int +win32_warn_bytes_api() +{ + return PyErr_WarnEx(PyExc_DeprecationWarning, + "The Windows bytes API has been deprecated, " + "use Unicode filenames instead", + 1); +} + +static PyObject* +win32_decode_filename(PyObject *obj) +{ + PyObject *unicode; + if (PyUnicode_Check(obj)) { + if (PyUnicode_READY(obj)) + return NULL; + Py_INCREF(obj); + return obj; + } + if (!PyUnicode_FSDecoder(obj, &unicode)) + return NULL; + if (win32_warn_bytes_api()) { + Py_DECREF(unicode); + return NULL; + } + return unicode; +} #endif /* MS_WINDOWS */ /* Return a dictionary corresponding to the POSIX environment table */ @@ -725,22 +753,6 @@ win32_error_object(char* function, PyObject* filename) return PyErr_SetFromWindowsErr(errno); } -static int -convert_to_unicode(PyObject **param) -{ - if (PyUnicode_CheckExact(*param)) - Py_INCREF(*param); - else if (PyUnicode_Check(*param)) - /* For a Unicode subtype that's not a Unicode object, - return a true Unicode object with the same data. */ - *param = PyUnicode_Copy(*param); - else - *param = PyUnicode_FromEncodedObject(*param, - Py_FileSystemDefaultEncoding, - "strict"); - return (*param) != NULL; -} - #endif /* MS_WINDOWS */ #if defined(PYOS_OS2) @@ -895,7 +907,7 @@ win32_1str(PyObject* args, char* func, char* wformat, BOOL (__stdcall *funcW)(LPWSTR)) { PyObject *uni; - char *ansi; + const char *ansi; BOOL result; if (PyArg_ParseTuple(args, wformat, &uni)) @@ -915,6 +927,8 @@ win32_1str(PyObject* args, char* func, if (!PyArg_ParseTuple(args, format, &ansi)) return NULL; + if (win32_warn_bytes_api()) + return NULL; Py_BEGIN_ALLOW_THREADS result = funcA(ansi); Py_END_ALLOW_THREADS @@ -1129,14 +1143,15 @@ attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG * /* Grab GetFinalPathNameByHandle dynamically from kernel32 */ static int has_GetFinalPathNameByHandle = 0; -static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, - DWORD); static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, DWORD); static int check_GetFinalPathNameByHandle() { HINSTANCE hKernel32; + DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, + DWORD); + /* only recheck */ if (!has_GetFinalPathNameByHandle) { @@ -1853,6 +1868,12 @@ posix_do_stat(PyObject *self, PyObject *args, if (!PyArg_ParseTuple(args, format, PyUnicode_FSConverter, &opath)) return NULL; +#ifdef MS_WINDOWS + if (win32_warn_bytes_api()) { + Py_DECREF(opath); + return NULL; + } +#endif path = PyBytes_AsString(opath); Py_BEGIN_ALLOW_THREADS res = (*statfunc)(path, &st); @@ -1885,8 +1906,7 @@ existence, or the inclusive-OR of R_OK, W_OK, and X_OK."); static PyObject * posix_access(PyObject *self, PyObject *args) { - PyObject *opath; - char *path; + const char *path; int mode; #ifdef MS_WINDOWS @@ -1904,14 +1924,13 @@ posix_access(PyObject *self, PyObject *args) /* Drop the argument parsing error as narrow strings are also valid. */ PyErr_Clear(); - if (!PyArg_ParseTuple(args, "O&i:access", - PyUnicode_FSConverter, &opath, &mode)) + if (!PyArg_ParseTuple(args, "yi:access", &path, &mode)) + return NULL; + if (win32_warn_bytes_api()) return NULL; - path = PyBytes_AsString(opath); Py_BEGIN_ALLOW_THREADS attr = GetFileAttributesA(path); Py_END_ALLOW_THREADS - Py_DECREF(opath); finish: if (attr == 0xFFFFFFFF) /* File does not exist, or cannot read attributes */ @@ -1923,6 +1942,7 @@ finish: || !(attr & FILE_ATTRIBUTE_READONLY) || (attr & FILE_ATTRIBUTE_DIRECTORY)); #else + PyObject *opath; int res; if (!PyArg_ParseTuple(args, "O&i:access", PyUnicode_FSConverter, &opath, &mode)) @@ -2042,7 +2062,7 @@ static PyObject * posix_chmod(PyObject *self, PyObject *args) { PyObject *opath = NULL; - char *path = NULL; + const char *path = NULL; int i; int res; #ifdef MS_WINDOWS @@ -2073,10 +2093,10 @@ posix_chmod(PyObject *self, PyObject *args) are also valid. */ PyErr_Clear(); - if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter, - &opath, &i)) + if (!PyArg_ParseTuple(args, "yi:chmod", &path, &i)) + return NULL; + if (win32_warn_bytes_api()) return NULL; - path = PyBytes_AsString(opath); Py_BEGIN_ALLOW_THREADS attr = GetFileAttributesA(path); if (attr != 0xFFFFFFFF) { @@ -2091,10 +2111,8 @@ posix_chmod(PyObject *self, PyObject *args) Py_END_ALLOW_THREADS if (!res) { win32_error("chmod", path); - Py_DECREF(opath); return NULL; } - Py_DECREF(opath); Py_INCREF(Py_None); return Py_None; #else /* MS_WINDOWS */ @@ -2450,51 +2468,56 @@ Create a hard link to a file."); static PyObject * win32_link(PyObject *self, PyObject *args) { - PyObject *osrc, *odst; - char *src, *dst; - BOOL rslt; - PyObject *usrc, *udst; + PyObject *src, *dst; + BOOL ok; - if (PyArg_ParseTuple(args, "UU:link", &usrc, &udst)) + if (PyArg_ParseTuple(args, "UU:link", &src, &dst)) { wchar_t *wsrc, *wdst; - wsrc = PyUnicode_AsUnicode(usrc); + + wsrc = PyUnicode_AsUnicode(src); if (wsrc == NULL) - return NULL; - wdst = PyUnicode_AsUnicode(udst); + goto error; + wdst = PyUnicode_AsUnicode(dst); if (wdst == NULL) - return NULL; + goto error; Py_BEGIN_ALLOW_THREADS - rslt = CreateHardLinkW(wdst, wsrc, NULL); + ok = CreateHardLinkW(wdst, wsrc, NULL); Py_END_ALLOW_THREADS - if (rslt == 0) + if (!ok) return win32_error("link", NULL); - Py_RETURN_NONE; } + else { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "O&O&:link", + PyUnicode_FSConverter, &src, + PyUnicode_FSConverter, &dst)) + return NULL; - /* Narrow strings also valid. */ - PyErr_Clear(); - - if (!PyArg_ParseTuple(args, "O&O&:link", PyUnicode_FSConverter, &osrc, - PyUnicode_FSConverter, &odst)) - return NULL; + if (win32_warn_bytes_api()) + goto error; - src = PyBytes_AsString(osrc); - dst = PyBytes_AsString(odst); + Py_BEGIN_ALLOW_THREADS + ok = CreateHardLinkA(PyBytes_AS_STRING(dst), + PyBytes_AS_STRING(src), + NULL); + Py_END_ALLOW_THREADS - Py_BEGIN_ALLOW_THREADS - rslt = CreateHardLinkA(dst, src, NULL); - Py_END_ALLOW_THREADS + Py_XDECREF(src); + Py_XDECREF(dst); - Py_DECREF(osrc); - Py_DECREF(odst); - if (rslt == 0) - return win32_error("link", NULL); + if (!ok) + return win32_error("link", NULL); + Py_RETURN_NONE; - Py_RETURN_NONE; + error: + Py_XDECREF(src); + Py_XDECREF(dst); + return NULL; + } } #endif /* MS_WINDOWS */ @@ -2519,7 +2542,8 @@ posix_listdir(PyObject *self, PyObject *args) HANDLE hFindFile; BOOL result; WIN32_FIND_DATA FileData; - PyObject *opath; + const char *path; + Py_ssize_t pathlen; char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */ char *bufptr = namebuf; Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */ @@ -2613,17 +2637,16 @@ posix_listdir(PyObject *self, PyObject *args) are also valid. */ PyErr_Clear(); - if (!PyArg_ParseTuple(args, "O&:listdir", - PyUnicode_FSConverter, &opath)) + if (!PyArg_ParseTuple(args, "y#:listdir", &path, &pathlen)) return NULL; - if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) { + if (win32_warn_bytes_api()) + return NULL; + if (pathlen+1 > MAX_PATH) { PyErr_SetString(PyExc_ValueError, "path too long"); - Py_DECREF(opath); return NULL; } - strcpy(namebuf, PyBytes_AsString(opath)); - len = PyObject_Size(opath); - Py_DECREF(opath); + strcpy(namebuf, path); + len = pathlen; if (len > 0) { char ch = namebuf[len-1]; if (ch != SEP && ch != ALTSEP && ch != ':') @@ -2915,11 +2938,9 @@ posix_fdlistdir(PyObject *self, PyObject *args) static PyObject * posix__getfullpathname(PyObject *self, PyObject *args) { - PyObject *opath; - char *path; + const char *path; char outbuf[MAX_PATH*2]; char *temp; -#ifdef MS_WINDOWS PyObject *po; if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) @@ -2953,19 +2974,17 @@ posix__getfullpathname(PyObject *self, PyObject *args) /* Drop the argument parsing error as narrow strings are also valid. */ PyErr_Clear(); -#endif - if (!PyArg_ParseTuple (args, "O&:_getfullpathname", - PyUnicode_FSConverter, &opath)) + if (!PyArg_ParseTuple (args, "y:_getfullpathname", + &path)) + return NULL; + if (win32_warn_bytes_api()) return NULL; - path = PyBytes_AsString(opath); if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf), outbuf, &temp)) { win32_error("GetFullPathName", path); - Py_DECREF(opath); return NULL; } - Py_DECREF(opath); if (PyUnicode_Check(PyTuple_GetItem(args, 0))) { return PyUnicode_Decode(outbuf, strlen(outbuf), Py_FileSystemDefaultEncoding, NULL); @@ -3069,8 +3088,7 @@ PyDoc_STRVAR(posix__isdir__doc__, static PyObject * posix__isdir(PyObject *self, PyObject *args) { - PyObject *opath; - char *path; + const char *path; PyObject *po; DWORD attributes; @@ -3088,11 +3106,10 @@ posix__isdir(PyObject *self, PyObject *args) are also valid. */ PyErr_Clear(); - if (!PyArg_ParseTuple(args, "O&:_isdir", - PyUnicode_FSConverter, &opath)) + if (!PyArg_ParseTuple(args, "y:_isdir", &path)) + return NULL; + if (win32_warn_bytes_api()) return NULL; - - path = PyBytes_AsString(opath); attributes = GetFileAttributesA(path); if (attributes == INVALID_FILE_ATTRIBUTES) Py_RETURN_FALSE; @@ -3113,8 +3130,7 @@ static PyObject * posix_mkdir(PyObject *self, PyObject *args) { int res; - PyObject *opath; - char *path; + const char *path; int mode = 0777; #ifdef MS_WINDOWS @@ -3136,22 +3152,21 @@ posix_mkdir(PyObject *self, PyObject *args) /* Drop the argument parsing error as narrow strings are also valid. */ PyErr_Clear(); - if (!PyArg_ParseTuple(args, "O&|i:mkdir", - PyUnicode_FSConverter, &opath, &mode)) + if (!PyArg_ParseTuple(args, "y|i:mkdir", &path, &mode)) + return NULL; + if (win32_warn_bytes_api()) return NULL; - path = PyBytes_AsString(opath); Py_BEGIN_ALLOW_THREADS res = CreateDirectoryA(path, NULL); Py_END_ALLOW_THREADS if (!res) { win32_error("mkdir", path); - Py_DECREF(opath); return NULL; } - Py_DECREF(opath); Py_INCREF(Py_None); return Py_None; #else + PyObject *opath; if (!PyArg_ParseTuple(args, "O&|i:mkdir", PyUnicode_FSConverter, &opath, &mode)) @@ -3265,44 +3280,54 @@ static PyObject * posix_rename(PyObject *self, PyObject *args) { #ifdef MS_WINDOWS - PyObject *o1, *o2; - wchar_t *w1, *w2; - char *p1, *p2; + PyObject *src, *dst; BOOL result; - if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2)) - goto error; - if (!convert_to_unicode(&o1)) - goto error; - if (!convert_to_unicode(&o2)) { - Py_DECREF(o1); - goto error; + if (PyArg_ParseTuple(args, "UU:rename", &src, &dst)) + { + wchar_t *wsrc, *wdst; + + wsrc = PyUnicode_AsUnicode(src); + if (wsrc == NULL) + return NULL; + wdst = PyUnicode_AsUnicode(dst); + if (wdst == NULL) + return NULL; + Py_BEGIN_ALLOW_THREADS + result = MoveFileW(wsrc, wdst); + Py_END_ALLOW_THREADS + if (!result) + return win32_error("rename", NULL); + Py_INCREF(Py_None); + return Py_None; } - w1 = PyUnicode_AsUnicode(o1); - if (w1 == NULL) - goto error; - w2 = PyUnicode_AsUnicode(o2); - if (w2 == NULL) - goto error; - Py_BEGIN_ALLOW_THREADS - result = MoveFileW(w1, w2); - Py_END_ALLOW_THREADS - Py_DECREF(o1); - Py_DECREF(o2); - if (!result) - return win32_error("rename", NULL); - Py_INCREF(Py_None); - return Py_None; + else { + PyErr_Clear(); + if (!PyArg_ParseTuple(args, "O&O&:rename", + PyUnicode_FSConverter, &src, + PyUnicode_FSConverter, &dst)) + return NULL; + + if (win32_warn_bytes_api()) + goto error; + + Py_BEGIN_ALLOW_THREADS + result = MoveFileA(PyBytes_AS_STRING(src), + PyBytes_AS_STRING(dst)); + Py_END_ALLOW_THREADS + + Py_XDECREF(src); + Py_XDECREF(dst); + + if (!result) + return win32_error("rename", NULL); + Py_INCREF(Py_None); + return Py_None; + error: - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2)) + Py_XDECREF(src); + Py_XDECREF(dst); return NULL; - Py_BEGIN_ALLOW_THREADS - result = MoveFileA(p1, p2); - Py_END_ALLOW_THREADS - if (!result) - return win32_error("rename", NULL); - Py_INCREF(Py_None); - return Py_None; + } #else return posix_2str(args, "O&O&:rename", rename); #endif @@ -3546,8 +3571,7 @@ posix_utime(PyObject *self, PyObject *args) PyObject *arg = Py_None; PyObject *obwpath; wchar_t *wpath = NULL; - PyObject *oapath; - char *apath; + const char *apath; HANDLE hFile; time_t atimesec, mtimesec; long ausec, musec; @@ -3571,11 +3595,11 @@ posix_utime(PyObject *self, PyObject *args) are also valid. */ PyErr_Clear(); - if (!PyArg_ParseTuple(args, "O&|O:utime", - PyUnicode_FSConverter, &oapath, &arg)) + if (!PyArg_ParseTuple(args, "y|O:utime", &apath, &arg)) + return NULL; + if (win32_warn_bytes_api()) return NULL; - apath = PyBytes_AsString(oapath); Py_BEGIN_ALLOW_THREADS hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, @@ -3583,10 +3607,8 @@ posix_utime(PyObject *self, PyObject *args) Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) { win32_error("utime", apath); - Py_DECREF(oapath); return NULL; } - Py_DECREF(oapath); } if (arg == Py_None) { @@ -6516,7 +6538,8 @@ static PyObject * win_symlink(PyObject *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = {"src", "dest", "target_is_directory", NULL}; - PyObject *src, *dest; + PyObject *osrc, *odest; + PyObject *usrc = NULL, *udest = NULL; wchar_t *wsrc, *wdest; int target_is_directory = 0; DWORD res; @@ -6528,24 +6551,25 @@ win_symlink(PyObject *self, PyObject *args, PyObject *kwargs) return PyErr_Format(PyExc_NotImplementedError, "CreateSymbolicLinkW not found"); } - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink", - kwlist, &src, &dest, &target_is_directory)) + if (!PyArg_ParseTupleAndKeywords( + args, kwargs, "OO|i:symlink", kwlist, + &osrc, &odest, &target_is_directory)) return NULL; + usrc = win32_decode_filename(osrc); + if (!usrc) + return NULL; + udest = win32_decode_filename(odest); + if (!udest) + goto error; + if (win32_can_symlink == 0) return PyErr_Format(PyExc_OSError, "symbolic link privilege not held"); - if (!convert_to_unicode(&src)) - return NULL; - if (!convert_to_unicode(&dest)) { - Py_DECREF(src); - return NULL; - } - - wsrc = PyUnicode_AsUnicode(src); + wsrc = PyUnicode_AsUnicode(usrc); if (wsrc == NULL) goto error; - wdest = PyUnicode_AsUnicode(dest); + wdest = PyUnicode_AsUnicode(udest); if (wsrc == NULL) goto error; @@ -6563,17 +6587,17 @@ win_symlink(PyObject *self, PyObject *args, PyObject *kwargs) res = Py_CreateSymbolicLinkW(wdest, wsrc, target_is_directory); Py_END_ALLOW_THREADS - Py_DECREF(src); - Py_DECREF(dest); + Py_DECREF(usrc); + Py_DECREF(udest); if (!res) - return win32_error_object("symlink", src); + return win32_error_object("symlink", osrc); Py_INCREF(Py_None); return Py_None; error: - Py_DECREF(src); - Py_DECREF(dest); + Py_XDECREF(usrc); + Py_XDECREF(udest); return NULL; } #endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ @@ -6791,6 +6815,12 @@ posix_open(PyObject *self, PyObject *args) PyUnicode_FSConverter, &ofile, &flag, &mode)) return NULL; +#ifdef MS_WINDOWS + if (win32_warn_bytes_api()) { + Py_DECREF(ofile); + return NULL; + } +#endif file = PyBytes_AsString(ofile); Py_BEGIN_ALLOW_THREADS fd = open(file, flag, mode); @@ -9290,6 +9320,10 @@ normal: PyUnicode_FSConverter, &ofilepath, &operation)) return NULL; + if (win32_warn_bytes_api()) { + Py_DECREF(ofilepath); + return NULL; + } filepath = PyBytes_AsString(ofilepath); Py_BEGIN_ALLOW_THREADS rc = ShellExecute((HWND)0, operation, filepath, |