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 |