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

5 files changed

lines changed

Original file line numberDiff line numberDiff line change

@@ -638,6 +638,11 @@ Deprecated features

638638

and will be removed in 3.8.

639639

(Contributed by Serhiy Storchaka in :issue:`21708`.)

640640
641+

* Undocumented support of general :term:`bytes-like objects <bytes-like object>`

642+

as paths in :mod:`os` functions is now deprecated.

643+

(Contributed by Serhiy Storchaka in :issue:`25791`.)

644+
645+
641646

Deprecated Python behavior

642647

--------------------------

643648
Original file line numberDiff line numberDiff line change

@@ -2626,6 +2626,7 @@ class Str(str):

26262626

else:

26272627

encoded = os.fsencode(support.TESTFN)

26282628

self.bytes_filenames.append(encoded)

2629+

self.bytes_filenames.append(bytearray(encoded))

26292630

self.bytes_filenames.append(memoryview(encoded))

26302631
26312632

self.filenames = self.bytes_filenames + self.unicode_filenames

@@ -2699,8 +2700,14 @@ def test_oserror_filename(self):

26992700

for filenames, func, *func_args in funcs:

27002701

for name in filenames:

27012702

try:

2702-

with bytes_filename_warn(False):

2703+

if isinstance(name, str):

27032704

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)

27042711

except OSError as err:

27052712

self.assertIs(err.filename, name)

27062713

else:

Original file line numberDiff line numberDiff line change

@@ -407,8 +407,10 @@ def test_fstat(self):

407407

def test_stat(self):

408408

self.assertTrue(posix.stat(support.TESTFN))

409409

self.assertTrue(posix.stat(os.fsencode(support.TESTFN)))

410-

self.assertTrue(posix.stat(bytearray(os.fsencode(support.TESTFN))))

411410
411+

self.assertWarnsRegex(DeprecationWarning,

412+

'should be string, bytes or integer, not',

413+

posix.stat, bytearray(os.fsencode(support.TESTFN)))

412414

self.assertRaisesRegex(TypeError,

413415

'should be string, bytes or integer, not',

414416

posix.stat, None)

Original file line numberDiff line numberDiff line change

@@ -43,6 +43,9 @@ Core and Builtins

4343

Library

4444

-------

4545
46+

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

47+

as paths in os functions is now deprecated.

48+
4649

- Issue #27661: Added tzinfo keyword argument to datetime.combine.

4750
4851

- Issue #27568: Prevent HTTPoxy attack (CVE-2016-1000110). Ignore the

Original file line numberDiff line numberDiff line change

@@ -891,7 +891,28 @@ path_converter(PyObject *o, void *p)

891891

}

892892

#endif

893893

}

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+

}

894903

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+

}

895916

#ifdef MS_WINDOWS

896917

if (win32_warn_bytes_api()) {

897918

return 0;

@@ -946,8 +967,14 @@ path_converter(PyObject *o, void *p)

946967

path->length = length;

947968

path->object = o;

948969

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+

}

951978

}

952979
953980

static void