]> granicus.if.org Git - python/commitdiff
Issue #27186: Add os.PathLike support to DirEntry
authorBrett Cannon <brett@python.org>
Fri, 10 Jun 2016 21:37:21 +0000 (14:37 -0700)
committerBrett Cannon <brett@python.org>
Fri, 10 Jun 2016 21:37:21 +0000 (14:37 -0700)
Initial patch thanks to Jelle Zijlstra.

Doc/library/os.rst
Lib/test/test_os.py
Misc/NEWS
Modules/posixmodule.c

index 46d49dfa5dd3ce7c2fed0dede7335ddaa47c837c..18b539b098e3d9298404684e58e36c26b7bac5e3 100644 (file)
@@ -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)
 
index 6853ebbd7fff2d09135f5e61548591e99ca7a896..3f955713c431e0f2201a3ba5410603f229d5bedd 100644 (file)
@@ -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')
 
index 39b1cffbe135b6e4b2a915b8b048d21f8e5e88aa..a4f857eea42c4f33ebd554dc093a10e2ece8505b 100644 (file)
--- 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).
index f4510dbec9a08a93e98178cf0b1d3b73cfbeb1d4..ecdeab4925cd11cc7209c6a9a6703031fbec319b 100644 (file)
@@ -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}
 };