Issue #26800: Undocumented support of general bytes-like objects

as paths in os functions is now deprecated.
This commit is contained in:
Serhiy Storchaka 2016-08-06 23:22:08 +03:00
parent 43b586b951
commit d73c31899e
5 changed files with 48 additions and 4 deletions

View File

@ -638,6 +638,11 @@ Deprecated features
and will be removed in 3.8. and will be removed in 3.8.
(Contributed by Serhiy Storchaka in :issue:`21708`.) (Contributed by Serhiy Storchaka in :issue:`21708`.)
* Undocumented support of general :term:`bytes-like objects <bytes-like object>`
as paths in :mod:`os` functions is now deprecated.
(Contributed by Serhiy Storchaka in :issue:`25791`.)
Deprecated Python behavior Deprecated Python behavior
-------------------------- --------------------------

View File

@ -2626,6 +2626,7 @@ class Str(str):
else: else:
encoded = os.fsencode(support.TESTFN) encoded = os.fsencode(support.TESTFN)
self.bytes_filenames.append(encoded) self.bytes_filenames.append(encoded)
self.bytes_filenames.append(bytearray(encoded))
self.bytes_filenames.append(memoryview(encoded)) self.bytes_filenames.append(memoryview(encoded))
self.filenames = self.bytes_filenames + self.unicode_filenames self.filenames = self.bytes_filenames + self.unicode_filenames
@ -2699,8 +2700,14 @@ def test_oserror_filename(self):
for filenames, func, *func_args in funcs: for filenames, func, *func_args in funcs:
for name in filenames: for name in filenames:
try: try:
if isinstance(name, str):
func(name, *func_args)
elif isinstance(name, bytes):
with bytes_filename_warn(False): with bytes_filename_warn(False):
func(name, *func_args) func(name, *func_args)
else:
with self.assertWarnsRegex(DeprecationWarning, 'should be'):
func(name, *func_args)
except OSError as err: except OSError as err:
self.assertIs(err.filename, name) self.assertIs(err.filename, name)
else: else:

View File

@ -407,8 +407,10 @@ def test_fstat(self):
def test_stat(self): def test_stat(self):
self.assertTrue(posix.stat(support.TESTFN)) self.assertTrue(posix.stat(support.TESTFN))
self.assertTrue(posix.stat(os.fsencode(support.TESTFN))) self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
self.assertTrue(posix.stat(bytearray(os.fsencode(support.TESTFN))))
self.assertWarnsRegex(DeprecationWarning,
'should be string, bytes or integer, not',
posix.stat, bytearray(os.fsencode(support.TESTFN)))
self.assertRaisesRegex(TypeError, self.assertRaisesRegex(TypeError,
'should be string, bytes or integer, not', 'should be string, bytes or integer, not',
posix.stat, None) posix.stat, None)

View File

@ -43,6 +43,9 @@ Core and Builtins
Library Library
------- -------
- Issue #26800: Undocumented support of general bytes-like objects
as paths in os functions is now deprecated.
- Issue #27661: Added tzinfo keyword argument to datetime.combine. - Issue #27661: Added tzinfo keyword argument to datetime.combine.
- Issue #27568: Prevent HTTPoxy attack (CVE-2016-1000110). Ignore the - Issue #27568: Prevent HTTPoxy attack (CVE-2016-1000110). Ignore the

View File

@ -891,7 +891,28 @@ path_converter(PyObject *o, void *p)
} }
#endif #endif
} }
else if (PyBytes_Check(o)) {
#ifdef MS_WINDOWS
if (win32_warn_bytes_api()) {
return 0;
}
#endif
bytes = o;
Py_INCREF(bytes);
}
else if (PyObject_CheckBuffer(o)) { else if (PyObject_CheckBuffer(o)) {
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"%s%s%s should be %s, not %.200s",
path->function_name ? path->function_name : "",
path->function_name ? ": " : "",
path->argument_name ? path->argument_name : "path",
path->allow_fd && path->nullable ? "string, bytes, integer or None" :
path->allow_fd ? "string, bytes or integer" :
path->nullable ? "string, bytes or None" :
"string or bytes",
Py_TYPE(o)->tp_name)) {
return 0;
}
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
if (win32_warn_bytes_api()) { if (win32_warn_bytes_api()) {
return 0; return 0;
@ -946,9 +967,15 @@ path_converter(PyObject *o, void *p)
path->length = length; path->length = length;
path->object = o; path->object = o;
path->fd = -1; path->fd = -1;
if (bytes == o) {
Py_DECREF(bytes);
return 1;
}
else {
path->cleanup = bytes; path->cleanup = bytes;
return Py_CLEANUP_SUPPORTED; return Py_CLEANUP_SUPPORTED;
} }
}
static void static void
argument_unavailable_error(const char *function_name, const char *argument_name) argument_unavailable_error(const char *function_name, const char *argument_name)