]> granicus.if.org Git - python/commitdiff
[3.5] bpo-30879: os.listdir() and os.scandir() now emit bytes names when (GH-2634...
authorSerhiy Storchaka <storchaka@gmail.com>
Tue, 11 Jul 2017 04:43:14 +0000 (07:43 +0300)
committerGitHub <noreply@github.com>
Tue, 11 Jul 2017 04:43:14 +0000 (07:43 +0300)
called with bytes-like argument.
(cherry picked from commit 1180e5a51871fa53ca6892e83fd2e69dc2600447)

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

index 6dc05eb7fde044f158efb8d4092b1aa7e14efc99..8ad6d8e31179e175ffc6335c47e8d93537e19dd4 100644 (file)
@@ -3185,6 +3185,28 @@ class TestScandir(unittest.TestCase):
         self.assertEqual(entry.path,
                          os.fsencode(os.path.join(self.path, 'file.txt')))
 
+    def test_bytes_like(self):
+        if os.name == "nt":
+            # On Windows, os.scandir(bytes) must raise an exception
+            for cls in bytearray, memoryview:
+                self.assertRaises(TypeError, os.scandir, cls(b'.'))
+            return
+
+        # Deprecated in 3.6.
+        self.create_file("file.txt")
+
+        for cls in bytearray, memoryview:
+            path_bytes = cls(os.fsencode(self.path))
+            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)
+
     def test_empty_path(self):
         self.assertRaises(FileNotFoundError, os.scandir, '')
 
index 57f793d1054d10e605823ea98604dc15dc40ee5d..b229cd340566aefb7745f275bfd8a29b2450294c 100644 (file)
@@ -577,17 +577,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):
+        # Deprecated in 3.6.
+        for cls in bytearray, memoryview:
+            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 4a8137f55f65ea1cedd2f5a93968396b57b855ae..966a011579f02d55fe9edad8ede33e23ce983124 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -59,6 +59,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 3dcebf496f3e0b7690f15c991c4e5eb5d9b019f4..d42416b0270ebb3066937ef624d421d080c45b48 100644 (file)
@@ -3642,8 +3642,8 @@ _posix_listdir(path_t *path, PyObject *list)
         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 = ".";
@@ -11960,7 +11960,7 @@ DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
     if (!joined_path)
         goto error;
 
-    if (!path->narrow || !PyBytes_Check(path->object)) {
+    if (!path->narrow || !PyObject_CheckBuffer(path->object)) {
         entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
         entry->path = PyUnicode_DecodeFSDefault(joined_path);
     }