Mercurial > hg-stable
changeset 18316:f36375576ed5
filecache: create an entry in _filecache when __set__ is called for a missing one
Preserve the invariant that if P is a filecached property on X then
P in X.__dict__ => P in X._filecache.
Previously, it was possible for a filecached property to become out of sync
with the filesystem if it was set before getting it first, since the initial
filecacheentry was created in __get__.
Old behaviour:
repo.prop = x
repo.invalidate() # prop has no entry in _filecache, it's not removed
# from __dict__
repo.prop # returns x like before without checking with the
# filesystem
New:
repo.prop = x # an empty entry is created in _filecache
repo.invalidate() # prop is removed from __dict__
repo.prop # recreates prop
author | Idan Kamara <idankk86@gmail.com> |
---|---|
date | Mon, 17 Dec 2012 15:25:45 +0200 |
parents | 216230643ae2 |
children | 365fecd984c7 |
files | mercurial/scmutil.py tests/test-filecache.py tests/test-filecache.py.out |
diffstat | 3 files changed, 31 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/scmutil.py Thu Jan 10 23:54:53 2013 +0200 +++ b/mercurial/scmutil.py Mon Dec 17 15:25:45 2012 +0200 @@ -950,6 +950,7 @@ def __get__(self, obj, type=None): # do we need to check if the file changed? if self.name in obj.__dict__: + assert self.name in obj._filecache, self.name return obj.__dict__[self.name] entry = obj._filecache.get(self.name) @@ -971,8 +972,15 @@ return entry.obj def __set__(self, obj, value): - if self.name in obj._filecache: - obj._filecache[self.name].obj = value # update cached copy + if self.name not in obj._filecache: + # we add an entry for the missing value because X in __dict__ + # implies X in _filecache + ce = filecacheentry(self.join(obj, self.path), False) + obj._filecache[self.name] = ce + else: + ce = obj._filecache[self.name] + + ce.obj = value # update cached copy obj.__dict__[self.name] = value # update copy returned by obj.x def __delete__(self, obj):
--- a/tests/test-filecache.py Thu Jan 10 23:54:53 2013 +0200 +++ b/tests/test-filecache.py Mon Dec 17 15:25:45 2012 +0200 @@ -101,6 +101,17 @@ # it repo.commit('.') +def setbeforeget(repo): + os.remove('x') + repo.cached = 0 + repo.invalidate() + print repo.cached + repo.invalidate() + f = open('x', 'w') + f.write('a') + f.close() + print repo.cached + print 'basic:' print basic(fakerepo()) @@ -109,3 +120,7 @@ print fakeuncacheable() test_filecache_synced() +print +print 'setbeforeget:' +print +setbeforeget(fakerepo())
--- a/tests/test-filecache.py.out Thu Jan 10 23:54:53 2013 +0200 +++ b/tests/test-filecache.py.out Mon Dec 17 15:25:45 2012 +0200 @@ -17,3 +17,9 @@ working directory now based on revision -1 repository tip rolled back to revision -1 (undo commit) working directory now based on revision -1 + +setbeforeget: + +0 +creating +None