Skip to content

Commit b5444ef

Browse files
committed
cache: Simplify invalidation logic to match existing behaviour
1 parent da6c598 commit b5444ef

File tree

2 files changed

+12
-38
lines changed

2 files changed

+12
-38
lines changed

confuse/cache.py

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
class CachedHandle(object):
88
"""Handle for a cached value computed by applying a template on the view.
99
"""
10-
# some sentinel objects
1110
_INVALID = object()
12-
_MISSING = object()
11+
"""Sentinel object to denote that the cached value is out-of-date."""
1312

1413
def __init__(self, view: ConfigView, template=templates.REQUIRED) -> None:
1514
self.value = self._INVALID
@@ -22,12 +21,8 @@ def get(self):
2221
Will re-compute the value using `view.get(template)` if it has been
2322
invalidated.
2423
25-
May raise a `NotFoundError` if the underlying view has been
26-
invalidated.
24+
May raise a `NotFoundError` if the underlying view is missing.
2725
"""
28-
if self.value is self._MISSING:
29-
# will raise a NotFoundError if no default value was provided
30-
self.value = templates.as_template(self.template).get_default_value()
3126
if self.value is self._INVALID:
3227
self.value = self.view.get(self.template)
3328
return self.value
@@ -37,11 +32,6 @@ def _invalidate(self):
3732
"""
3833
self.value = self._INVALID
3934

40-
def _set_view_missing(self):
41-
"""Invalidate the handle, will raise `NotFoundError` on `get()`.
42-
"""
43-
self.value = self._MISSING
44-
4535

4636
class CachedViewMixin:
4737
def __init__(self, *args, **kwargs):
@@ -62,9 +52,7 @@ def __getitem__(self, key) -> "CachedConfigView":
6252
def __setitem__(self, key, value):
6353
subview: CachedConfigView = self[key]
6454
# invalidate the existing handles up and down the view tree
65-
for handle in subview.handles:
66-
handle._invalidate()
67-
subview._invalidate_descendants(value)
55+
subview._invalidate_descendants()
6856
self._invalidate_ancestors()
6957

7058
return super().__setitem__(key, value)
@@ -82,24 +70,13 @@ def _invalidate_ancestors(self):
8270
break
8371
parent = parent.parent
8472

85-
def _invalidate_descendants(self, new_val):
86-
"""Invalidate the handles for (sub)keys that were updated and
87-
set_view_missing for keys that are absent in new_val.
73+
def _invalidate_descendants(self):
74+
"""Invalidate the handles for (sub)keys that were updated.
8875
"""
76+
for handle in self.handles:
77+
handle._invalidate()
8978
for subview in self.subviews.values():
90-
try:
91-
subval = new_val[subview.key]
92-
except (KeyError, IndexError, TypeError):
93-
# the old key doesn't exist in the new value anymore-
94-
# set view as missing for the handles.
95-
for handle in subview.handles:
96-
handle._set_view_missing()
97-
subval = None
98-
else:
99-
# old key is present, possibly with a new value- invalidate.
100-
for handle in subview.handles:
101-
handle._invalidate()
102-
subview._invalidate_descendants(subval)
79+
subview._invalidate_descendants()
10380

10481
def get_handle(self, template=templates.REQUIRED):
10582
"""Retreive a `CachedHandle` for the current view and template.

test/test_cache.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import confuse
44
from confuse.cache import CachedConfigView, CachedHandle, CachedRootView
5-
from confuse.exceptions import NotFoundError
65
from confuse.templates import Sequence
76

87

@@ -35,19 +34,17 @@ def test_missing(self):
3534
handle: CachedHandle = view.get_handle(Sequence(int))
3635

3736
self.config['x'] = {'p': [4, 5]}
38-
# new dict doesn't have a 'y' key
39-
with self.assertRaises(NotFoundError):
40-
handle.get()
37+
# new dict doesn't have a 'y' key, but according to the view-theory,
38+
# it will get the value from the older view that has been shadowed.
39+
self.assertEqual(handle.get(), [1, 2])
4140

4241
def test_missing2(self):
4342
view: CachedConfigView = self.config['x']['w']
4443
handle = view.get_handle(str)
4544
self.assertEqual(handle.get(), 'z')
4645

4746
self.config['x'] = {'y': [4, 5]}
48-
# new dict doesn't have a 'w' key
49-
with self.assertRaises(NotFoundError):
50-
handle.get()
47+
self.assertEqual(handle.get(), 'z')
5148

5249
def test_list_update(self):
5350
view: CachedConfigView = self.config['a'][1]

0 commit comments

Comments
 (0)