# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1531516812 25200
#      Fri Jul 13 14:20:12 2018 -0700
# Node ID 3b072388ca787e57f7b38c8e81f7f45b391cdff7
# Parent  35b3f686157a27db8a1a0a4ab9eab5f4583a5fdf
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

diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -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