summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/os.rst6
-rw-r--r--Lib/test/test_os.py23
-rw-r--r--Misc/NEWS5
-rw-r--r--Modules/posixmodule.c10
4 files changed, 39 insertions, 5 deletions
diff --git a/Doc/library/os.rst b/Doc/library/os.rst
index 46d49df..18b539b 100644
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -1994,6 +1994,9 @@ features:
control over errors, you can catch :exc:`OSError` when calling one of the
``DirEntry`` methods and handle as appropriate.
+ To be directly usable as a path-like object, ``DirEntry`` implements the
+ :class:`os.PathLike` interface.
+
Attributes and methods on a ``DirEntry`` instance are as follows:
.. attribute:: name
@@ -2106,6 +2109,9 @@ features:
.. versionadded:: 3.5
+ .. versionchanged:: 3.6
+ Added support for the :class:`os.PathLike` interface.
+
.. function:: stat(path, \*, dir_fd=None, follow_symlinks=True)
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 6853ebb..3f95571 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -2824,11 +2824,13 @@ class TestScandir(unittest.TestCase):
def setUp(self):
self.path = os.path.realpath(support.TESTFN)
+ self.bytes_path = os.fsencode(self.path)
self.addCleanup(support.rmtree, self.path)
os.mkdir(self.path)
def create_file(self, name="file.txt"):
- filename = os.path.join(self.path, name)
+ path = self.bytes_path if isinstance(name, bytes) else self.path
+ filename = os.path.join(path, name)
create_file(filename, b'python')
return filename
@@ -2917,15 +2919,16 @@ class TestScandir(unittest.TestCase):
self.check_entry(entry, 'symlink_file.txt', False, True, True)
def get_entry(self, name):
- entries = list(os.scandir(self.path))
+ path = self.bytes_path if isinstance(name, bytes) else self.path
+ entries = list(os.scandir(path))
self.assertEqual(len(entries), 1)
entry = entries[0]
self.assertEqual(entry.name, name)
return entry
- def create_file_entry(self):
- filename = self.create_file()
+ def create_file_entry(self, name='file.txt'):
+ filename = self.create_file(name=name)
return self.get_entry(os.path.basename(filename))
def test_current_directory(self):
@@ -2946,6 +2949,18 @@ class TestScandir(unittest.TestCase):
entry = self.create_file_entry()
self.assertEqual(repr(entry), "<DirEntry 'file.txt'>")
+ def test_fspath_protocol(self):
+ entry = self.create_file_entry()
+ self.assertEqual(os.fspath(entry), os.path.join(self.path, 'file.txt'))
+
+ def test_fspath_protocol_bytes(self):
+ bytes_filename = os.fsencode('bytesfile.txt')
+ bytes_entry = self.create_file_entry(name=bytes_filename)
+ fspath = os.fspath(bytes_entry)
+ self.assertIsInstance(fspath, bytes)
+ self.assertEqual(fspath,
+ os.path.join(os.fsencode(self.path),bytes_filename))
+
def test_removed_dir(self):
path = os.path.join(self.path, 'dir')
diff --git a/Misc/NEWS b/Misc/NEWS
index 39b1cff..a4f857e 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -38,11 +38,14 @@ Core and Builtins
Library
-------
+- Issue #27186: Add os.PathLike support to DirEntry (part of PEP 519).
+ Initial patch by Jelle Zijlstra.
+
- Issue #20900: distutils register command now decodes HTTP responses
correctly. Initial patch by ingrid.
- Issue #27186: Add os.PathLike support to pathlib, removing its provisional
- status (part of PEP 519).
+ status (part of PEP 519). Initial patch by Dusty Phillips.
- Issue #27186: Add support for os.PathLike objects to os.fsencode() and
os.fsdecode() (part of PEP 519).
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index f4510db..ecdeab4 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -11718,6 +11718,13 @@ DirEntry_repr(DirEntry *self)
return PyUnicode_FromFormat("<DirEntry %R>", self->name);
}
+static PyObject *
+DirEntry_fspath(DirEntry *self)
+{
+ Py_INCREF(self->path);
+ return self->path;
+}
+
static PyMemberDef DirEntry_members[] = {
{"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
"the entry's base filename, relative to scandir() \"path\" argument"},
@@ -11742,6 +11749,9 @@ static PyMethodDef DirEntry_methods[] = {
{"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
"return inode of the entry; cached per entry",
},
+ {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
+ "returns the path for the entry",
+ },
{NULL}
};