changeset 38676:3b072388ca78

scmutil: rewrite docstring for filecache The old docstring was incorrect in that it said that subsequent calls perform a stat() and refresh the object if things change. This is not how things work: __get__ populates obj.__dict__[self.sname] with the result of the decorated function and returns this value without validation on subsequent calls, if available. The correct usage of this type is kinda wonky. It would probably benefit from a refactor. But I don't have time to do that right now. But we can change the docstring so others aren't entrapped by its lies (like I was when using repofilecache in a Mozilla extension). Differential Revision: https://phab.mercurial-scm.org/D3943
author Gregory Szorc <gregory.szorc@gmail.com>
date Fri, 13 Jul 2018 14:20:12 -0700
parents 35b3f686157a
children 2a227782e754
files mercurial/scmutil.py
diffstat 1 files changed, 22 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/scmutil.py	Thu Jul 12 22:35:54 2018 +0530
+++ b/mercurial/scmutil.py	Fri Jul 13 14:20:12 2018 -0700
@@ -1166,21 +1166,32 @@
             entry.refresh()
 
 class filecache(object):
-    '''A property like decorator that tracks files under .hg/ for updates.
+    """A property like decorator that tracks files under .hg/ for updates.
 
-    Records stat info when called in _filecache.
+    On first access, the files defined as arguments are stat()ed and the
+    results cached. The decorated function is called. The results are stashed
+    away in a ``_filecache`` dict on the object whose method is decorated.
 
-    On subsequent calls, compares old stat info with new info, and recreates the
-    object when any of the files changes, updating the new stat info in
-    _filecache.
+    On subsequent access, the cached result is returned.
+
+    On external property set operations, stat() calls are performed and the new
+    value is cached.
+
+    On property delete operations, cached data is removed.
 
-    Mercurial either atomic renames or appends for files under .hg,
-    so to ensure the cache is reliable we need the filesystem to be able
-    to tell us if a file has been replaced. If it can't, we fallback to
-    recreating the object on every call (essentially the same behavior as
-    propertycache).
+    When using the property API, cached data is always returned, if available:
+    no stat() is performed to check if the file has changed and if the function
+    needs to be called to reflect file changes.
 
-    '''
+    Others can muck about with the state of the ``_filecache`` dict. e.g. they
+    can populate an entry before the property's getter is called. In this case,
+    entries in ``_filecache`` will be used during property operations,
+    if available. If the underlying file changes, it is up to external callers
+    to reflect this by e.g. calling ``delattr(obj, attr)`` to remove the cached
+    method result as well as possibly calling ``del obj._filecache[attr]`` to
+    remove the ``filecacheentry``.
+    """
+
     def __init__(self, *paths):
         self.paths = paths