]> granicus.if.org Git - python/commitdiff
bpo-30879: os.listdir() and os.scandir() now emit bytes names when (#2634)
authorSerhiy Storchaka <storchaka@gmail.com>
Tue, 11 Jul 2017 03:36:46 +0000 (06:36 +0300)
committerGitHub <noreply@github.com>
Tue, 11 Jul 2017 03:36:46 +0000 (06:36 +0300)
called with bytes-like argument.

Lib/test/test_os.py
Lib/test/test_posix.py
Misc/NEWS
Modules/posixmodule.c

index 49e5a37cd209d79b64e586ab773f1d5b36f57780..5ff18cea13479b425a5f345e257114ee3a822aa8 100644 (file)
@@ -3420,6 +3420,22 @@ class TestScandir(unittest.TestCase):
         self.assertEqual(entry.path,
                          os.fsencode(os.path.join(self.path, 'file.txt')))
 
+    def test_bytes_like(self):
+        self.create_file("file.txt")
+
+        for cls in bytearray, memoryview:
+            path_bytes = cls(os.fsencode(self.path))
+            with self.assertWarns(DeprecationWarning):
+                entries = list(os.scandir(path_bytes))
+            self.assertEqual(len(entries), 1, entries)
+            entry = entries[0]
+
+            self.assertEqual(entry.name, b'file.txt')
+            self.assertEqual(entry.path,
+                             os.fsencode(os.path.join(self.path, 'file.txt')))
+            self.assertIs(type(entry.name), bytes)
+            self.assertIs(type(entry.path), bytes)
+
     @unittest.skipUnless(os.listdir in os.supports_fd,
                          'fd support for listdir required for this test.')
     def test_fd(self):
index aa1b0e44635e1639cdcee215f4fe812ed05c4ea7..22b050d4d723c81c630078009dc92a4d5c04fd67 100644 (file)
@@ -643,17 +643,25 @@ class PosixTester(unittest.TestCase):
         self.assertRaises(OSError, posix.chdir, support.TESTFN)
 
     def test_listdir(self):
-        self.assertTrue(support.TESTFN in posix.listdir(os.curdir))
+        self.assertIn(support.TESTFN, posix.listdir(os.curdir))
 
     def test_listdir_default(self):
         # When listdir is called without argument,
         # it's the same as listdir(os.curdir).
-        self.assertTrue(support.TESTFN in posix.listdir())
+        self.assertIn(support.TESTFN, posix.listdir())
 
     def test_listdir_bytes(self):
         # When listdir is called with a bytes object,
         # the returned strings are of type bytes.
-        self.assertTrue(os.fsencode(support.TESTFN) in posix.listdir(b'.'))
+        self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.'))
+
+    def test_listdir_bytes_like(self):
+        for cls in bytearray, memoryview:
+            with self.assertWarns(DeprecationWarning):
+                names = posix.listdir(cls(b'.'))
+            self.assertIn(os.fsencode(support.TESTFN), names)
+            for name in names:
+                self.assertIs(type(name), bytes)
 
     @unittest.skipUnless(posix.listdir in os.supports_fd,
                          "test needs fd support for posix.listdir()")
index 2f2fafff5ee910e479bf1f7b2de0f35082795607..ce4874ac36df6a4b2c6da9937c3187e93ba9c300 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -376,6 +376,9 @@ Extension Modules
 Library
 -------
 
+- bpo-30879: os.listdir() and os.scandir() now emit bytes names when called
+  with bytes-like argument.
+
 - bpo-30746: Prohibited the '=' character in environment variable names in
   ``os.putenv()`` and ``os.spawn*()``.
 
index 194a2b5aa563d1d4a59366d5e4b9a41feea7a5d8..0c6723fb09f114b1a9f23662f331983e78e2c7e1 100644 (file)
@@ -1037,6 +1037,8 @@ path_converter(PyObject *o, void *p)
         Py_INCREF(bytes);
     }
     else if (is_buffer) {
+        /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code
+           after removing suport of non-bytes buffer objects. */
         if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
             "%s%s%s should be %s, not %.200s",
             path->function_name ? path->function_name : "",
@@ -3588,8 +3590,8 @@ _posix_listdir(path_t *path, PyObject *list)
         const char *name;
         if (path->narrow) {
             name = path->narrow;
-            /* only return bytes if they specified a bytes object */
-            return_str = !(PyBytes_Check(path->object));
+            /* only return bytes if they specified a bytes-like object */
+            return_str = !PyObject_CheckBuffer(path->object);
         }
         else {
             name = ".";
@@ -11842,7 +11844,7 @@ DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
             goto error;
     }
 
-    if (!path->narrow || !PyBytes_Check(path->object)) {
+    if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
         entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
         if (joined_path)
             entry->path = PyUnicode_DecodeFSDefault(joined_path);