summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/whatsnew/3.3.rst4
-rw-r--r--Lib/test/test_genericpath.py21
-rw-r--r--Lib/test/test_ntpath.py7
-rw-r--r--Lib/test/test_os.py44
-rw-r--r--Lib/test/test_pep277.py9
-rw-r--r--Lib/test/test_posixpath.py12
-rw-r--r--Misc/NEWS4
-rw-r--r--Modules/posixmodule.c328
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.
diff --git a/Misc/NEWS b/Misc/NEWS
index 3ed7e7a..6e77935 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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,