Issue #26800: Undocumented support of general bytes-like objects · python/cpython@d73c318 (original) (raw)

5 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -638,6 +638,11 @@ Deprecated features
638 638 and will be removed in 3.8.
639 639 (Contributed by Serhiy Storchaka in :issue:`21708`.)
640 640
641 +* Undocumented support of general :term:`bytes-like objects `
642 + as paths in :mod:`os` functions is now deprecated.
643 + (Contributed by Serhiy Storchaka in :issue:`25791`.)
644 +
645 +
641 646 Deprecated Python behavior
642 647 --------------------------
643 648
Original file line number Diff line number Diff line change
@@ -2626,6 +2626,7 @@ class Str(str):
2626 2626 else:
2627 2627 encoded = os.fsencode(support.TESTFN)
2628 2628 self.bytes_filenames.append(encoded)
2629 +self.bytes_filenames.append(bytearray(encoded))
2629 2630 self.bytes_filenames.append(memoryview(encoded))
2630 2631
2631 2632 self.filenames = self.bytes_filenames + self.unicode_filenames
@@ -2699,8 +2700,14 @@ def test_oserror_filename(self):
2699 2700 for filenames, func, *func_args in funcs:
2700 2701 for name in filenames:
2701 2702 try:
2702 -with bytes_filename_warn(False):
2703 +if isinstance(name, str):
2703 2704 func(name, *func_args)
2705 +elif isinstance(name, bytes):
2706 +with bytes_filename_warn(False):
2707 +func(name, *func_args)
2708 +else:
2709 +with self.assertWarnsRegex(DeprecationWarning, 'should be'):
2710 +func(name, *func_args)
2704 2711 except OSError as err:
2705 2712 self.assertIs(err.filename, name)
2706 2713 else:
Original file line number Diff line number Diff line change
@@ -407,8 +407,10 @@ def test_fstat(self):
407 407 def test_stat(self):
408 408 self.assertTrue(posix.stat(support.TESTFN))
409 409 self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))
410 -self.assertTrue(posix.stat(bytearray(os.fsencode(support.TESTFN))))
411 410
411 +self.assertWarnsRegex(DeprecationWarning,
412 +'should be string, bytes or integer, not',
413 +posix.stat, bytearray(os.fsencode(support.TESTFN)))
412 414 self.assertRaisesRegex(TypeError,
413 415 'should be string, bytes or integer, not',
414 416 posix.stat, None)
Original file line number Diff line number Diff line change
@@ -43,6 +43,9 @@ Core and Builtins
43 43 Library
44 44 -------
45 45
46 +- Issue #26800: Undocumented support of general bytes-like objects
47 + as paths in os functions is now deprecated.
48 +
46 49 - Issue #27661: Added tzinfo keyword argument to datetime.combine.
47 50
48 51 - Issue #27568: Prevent HTTPoxy attack (CVE-2016-1000110). Ignore the
Original file line number Diff line number Diff line change
@@ -891,7 +891,28 @@ path_converter(PyObject *o, void *p)
891 891 }
892 892 #endif
893 893 }
894 +else if (PyBytes_Check(o)) {
895 +#ifdef MS_WINDOWS
896 +if (win32_warn_bytes_api()) {
897 +return 0;
898 + }
899 +#endif
900 +bytes = o;
901 +Py_INCREF(bytes);
902 + }
894 903 else if (PyObject_CheckBuffer(o)) {
904 +if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
905 +"%s%s%s should be %s, not %.200s",
906 +path->function_name ? path->function_name : "",
907 +path->function_name ? ": " : "",
908 +path->argument_name ? path->argument_name : "path",
909 +path->allow_fd && path->nullable ? "string, bytes, integer or None" :
910 +path->allow_fd ? "string, bytes or integer" :
911 +path->nullable ? "string, bytes or None" :
912 +"string or bytes",
913 +Py_TYPE(o)->tp_name)) {
914 +return 0;
915 + }
895 916 #ifdef MS_WINDOWS
896 917 if (win32_warn_bytes_api()) {
897 918 return 0;
@@ -946,8 +967,14 @@ path_converter(PyObject *o, void *p)
946 967 path->length = length;
947 968 path->object = o;
948 969 path->fd = -1;
949 -path->cleanup = bytes;
950 -return Py_CLEANUP_SUPPORTED;
970 +if (bytes == o) {
971 +Py_DECREF(bytes);
972 +return 1;
973 + }
974 +else {
975 +path->cleanup = bytes;
976 +return Py_CLEANUP_SUPPORTED;
977 + }
951 978 }
952 979
953 980 static void