Commits

Antoine Pitrou committed e9fbf45

Remove stat caching

Comments (0)

Files changed (3)

 .. method:: Path.stat()
 
    Return information about this path (similarly to :func:`os.stat`).
-   The result is cached accross calls.
+   The result is looked up at each call to this method.
 
       >>> p = Path('setup.py')
       >>> p.stat().st_size
       >>> p.stat().st_mtime
       1327883547.852554
 
-   This information can also be accessed through :ref:`helper attributes <st_attrs>`.
-
-
-.. method:: Path.restat()
-
-   Like :meth:`Path.stat`, but ignores the cached value and always invokes
-   the underlying system call.
-
 
 .. method:: Path.chmod(mode)
 
       >>> p.stat().st_mode
       33277
       >>> p.chmod(0o444)
-      >>> p.restat().st_mode
+      >>> p.stat().st_mode
       33060
 
 
 class Path(PurePath):
     __slots__ = (
         '_accessor',
-        '_cached_stat',
         '_closed',
     )
 
         parts = self._parts + [part]
         return self._from_parsed_parts(self._drv, self._root, parts)
 
-    @property
-    def _stat(self):
-        try:
-            return self._cached_stat
-        except AttributeError:
-            pass
-        st = self._accessor.stat(self)
-        self._cached_stat = st
-        return st
-
     def __enter__(self):
         if self._closed:
             self._raise_closed()
         if s is None:
             # No symlink resolution => for consistency, raise an error if
             # the path doesn't exist or is forbidden
-            self._stat
+            self.stat()
             s = str(self.absolute())
         # Now we have no symlinks in the path, it's safe to normalize it.
         normed = self._flavour.pathmod.normpath(s)
         Return the result of the stat() system call on this path, like
         os.stat() does.
         """
-        return self._stat
-
-    def restat(self):
-        """
-        Same as stat(), but resets the internal cache to force a fresh value.
-        """
-        try:
-            del self._cached_stat
-        except AttributeError:
-            pass
-        return self._stat
+        return self._accessor.stat(self)
 
     @property
     def owner(self):
         Return the login name of the file owner.
         """
         import pwd
-        return pwd.getpwuid(self._stat.st_uid).pw_name
+        return pwd.getpwuid(self.stat().st_uid).pw_name
 
     @property
     def group(self):
         Return the group name of the file gid.
         """
         import grp
-        return grp.getgrgid(self._stat.st_gid).gr_name
+        return grp.getgrgid(self.stat().st_gid).gr_name
 
     def raw_open(self, flags, mode=0o777):
         """
         Whether this path exists.
         """
         try:
-            self.restat()
+            self.stat()
         except OSError as e:
             if e.errno != ENOENT:
                 raise
         Whether this path is a directory.
         """
         try:
-            return S_ISDIR(self._stat.st_mode)
+            return S_ISDIR(self.stat().st_mode)
         except OSError as e:
             if e.errno != ENOENT:
                 raise
         to regular files).
         """
         try:
-            return S_ISREG(self._stat.st_mode)
+            return S_ISREG(self.stat().st_mode)
         except OSError as e:
             if e.errno != ENOENT:
                 raise
         # Clear writable bit
         new_mode = mode & ~0o222
         p.chmod(new_mode)
-        self.assertEqual(p.restat().st_mode, new_mode)
+        self.assertEqual(p.stat().st_mode, new_mode)
         # Set writable bit
         new_mode = mode | 0o222
         p.chmod(new_mode)
-        self.assertEqual(p.restat().st_mode, new_mode)
+        self.assertEqual(p.stat().st_mode, new_mode)
 
     # XXX also need a test for lchmod
 
         p = self.cls(BASE) / 'fileA'
         st = p.stat()
         self.assertEqual(p.stat(), st)
-        self.assertEqual(p.restat(), st)
         # Change file mode by flipping write bit
         p.chmod(st.st_mode ^ 0o222)
         self.addCleanup(p.chmod, st.st_mode)
-        # Cached value didn't change
-        self.assertEqual(p.stat(), st)
-        # restat() invalidates the cache
-        self.assertNotEqual(p.restat(), st)
         self.assertNotEqual(p.stat(), st)
 
     @with_symlinks
     def test_unlink(self):
         p = self.cls(BASE) / 'fileA'
         p.unlink()
-        self.assertFileNotFound(p.restat)
+        self.assertFileNotFound(p.stat)
         self.assertFileNotFound(p.unlink)
 
     def test_rmdir(self):
         for q in p:
             q.unlink()
         p.rmdir()
-        self.assertFileNotFound(p.restat)
+        self.assertFileNotFound(p.stat)
         self.assertFileNotFound(p.unlink)
 
     def test_rename(self):
         q = P / 'dirA' / 'fileAA'
         p.rename(q)
         self.assertEqual(q.stat().st_size, size)
-        self.assertFileNotFound(p.restat)
+        self.assertFileNotFound(p.stat)
         # Renaming to a str of a relative path
         r = rel_join('fileAAA')
         q.rename(r)
         self.assertEqual(os.stat(r).st_size, size)
-        self.assertFileNotFound(q.restat)
+        self.assertFileNotFound(q.stat)
 
     def test_replace(self):
         P = self.cls(BASE)
         q = P / 'dirA' / 'fileAA'
         p.replace(q)
         self.assertEqual(q.stat().st_size, size)
-        self.assertFileNotFound(p.restat)
+        self.assertFileNotFound(p.stat)
         # Replacing another (existing) path
         r = rel_join('dirB', 'fileB')
         q.replace(r)
         self.assertEqual(os.stat(r).st_size, size)
-        self.assertFileNotFound(q.restat)
+        self.assertFileNotFound(q.stat)
 
     def test_touch_common(self):
         P = self.cls(BASE)
         self.assertFalse(p.exists())
         p.touch()
         self.assertTrue(p.exists())
-        old_mtime = p.restat().st_mtime
+        old_mtime = p.stat().st_mtime
         # Rewind the mtime sufficiently far in the past to work around
         # filesystem-specific timestamp granularity.
         os.utime(str(p), (old_mtime - 10, old_mtime - 10))
         # The file mtime is refreshed by calling touch() again
         p.touch()
-        self.assertGreaterEqual(p.restat().st_mtime, old_mtime)
+        self.assertGreaterEqual(p.stat().st_mtime, old_mtime)
         p = P / 'newfileB'
         self.assertFalse(p.exists())
         p.touch(mode=0o700, exist_ok=False)