summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-07-11 04:43:14 (GMT)
committerGitHub <noreply@github.com>2017-07-11 04:43:14 (GMT)
commit7527c32f5fedc3260d767900f1014495c0a1b7a5 (patch)
treed3291f8f27925dea45b58d4f6334cc52eb332f3d
parent7f567e7472dd6c3d066eec1c204301df251484b5 (diff)
downloadcpython-7527c32f5fedc3260d767900f1014495c0a1b7a5.zip
cpython-7527c32f5fedc3260d767900f1014495c0a1b7a5.tar.gz
cpython-7527c32f5fedc3260d767900f1014495c0a1b7a5.tar.bz2
[3.5] bpo-30879: os.listdir() and os.scandir() now emit bytes names when (GH-2634) (#2657)
called with bytes-like argument. (cherry picked from commit 1180e5a51871fa53ca6892e83fd2e69dc2600447)
-rw-r--r--Lib/test/test_os.py22
-rw-r--r--Lib/test/test_posix.py14
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/posixmodule.c6
4 files changed, 39 insertions, 6 deletions
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 6dc05eb..8ad6d8e 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -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, '')
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index 57f793d..b229cd3 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -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()")
diff --git a/Misc/NEWS b/Misc/NEWS
index 4a8137f..966a011 100644
--- 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*()``.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 3dcebf4..d42416b 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -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);
}