Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/mako/cache.py : 44%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# mako/cache.py
2# Copyright 2006-2020 the Mako authors and contributors <see AUTHORS file>
3#
4# This module is part of Mako and is released under
5# the MIT License: http://www.opensource.org/licenses/mit-license.php
7from mako import compat
8from mako import util
10_cache_plugins = util.PluginLoader("mako.cache")
12register_plugin = _cache_plugins.register
13register_plugin("beaker", "mako.ext.beaker_cache", "BeakerCacheImpl")
16class Cache(object):
18 """Represents a data content cache made available to the module
19 space of a specific :class:`.Template` object.
21 .. versionadded:: 0.6
22 :class:`.Cache` by itself is mostly a
23 container for a :class:`.CacheImpl` object, which implements
24 a fixed API to provide caching services; specific subclasses exist to
25 implement different
26 caching strategies. Mako includes a backend that works with
27 the Beaker caching system. Beaker itself then supports
28 a number of backends (i.e. file, memory, memcached, etc.)
30 The construction of a :class:`.Cache` is part of the mechanics
31 of a :class:`.Template`, and programmatic access to this
32 cache is typically via the :attr:`.Template.cache` attribute.
34 """
36 impl = None
37 """Provide the :class:`.CacheImpl` in use by this :class:`.Cache`.
39 This accessor allows a :class:`.CacheImpl` with additional
40 methods beyond that of :class:`.Cache` to be used programmatically.
42 """
44 id = None
45 """Return the 'id' that identifies this cache.
47 This is a value that should be globally unique to the
48 :class:`.Template` associated with this cache, and can
49 be used by a caching system to name a local container
50 for data specific to this template.
52 """
54 starttime = None
55 """Epochal time value for when the owning :class:`.Template` was
56 first compiled.
58 A cache implementation may wish to invalidate data earlier than
59 this timestamp; this has the effect of the cache for a specific
60 :class:`.Template` starting clean any time the :class:`.Template`
61 is recompiled, such as when the original template file changed on
62 the filesystem.
64 """
66 def __init__(self, template, *args):
67 # check for a stale template calling the
68 # constructor
69 if isinstance(template, compat.string_types) and args:
70 return
71 self.template = template
72 self.id = template.module.__name__
73 self.starttime = template.module._modified_time
74 self._def_regions = {}
75 self.impl = self._load_impl(self.template.cache_impl)
77 def _load_impl(self, name):
78 return _cache_plugins.load(name)(self)
80 def get_or_create(self, key, creation_function, **kw):
81 """Retrieve a value from the cache, using the given creation function
82 to generate a new value."""
84 return self._ctx_get_or_create(key, creation_function, None, **kw)
86 def _ctx_get_or_create(self, key, creation_function, context, **kw):
87 """Retrieve a value from the cache, using the given creation function
88 to generate a new value."""
90 if not self.template.cache_enabled:
91 return creation_function()
93 return self.impl.get_or_create(
94 key, creation_function, **self._get_cache_kw(kw, context)
95 )
97 def set(self, key, value, **kw):
98 r"""Place a value in the cache.
100 :param key: the value's key.
101 :param value: the value.
102 :param \**kw: cache configuration arguments.
104 """
106 self.impl.set(key, value, **self._get_cache_kw(kw, None))
108 put = set
109 """A synonym for :meth:`.Cache.set`.
111 This is here for backwards compatibility.
113 """
115 def get(self, key, **kw):
116 r"""Retrieve a value from the cache.
118 :param key: the value's key.
119 :param \**kw: cache configuration arguments. The
120 backend is configured using these arguments upon first request.
121 Subsequent requests that use the same series of configuration
122 values will use that same backend.
124 """
125 return self.impl.get(key, **self._get_cache_kw(kw, None))
127 def invalidate(self, key, **kw):
128 r"""Invalidate a value in the cache.
130 :param key: the value's key.
131 :param \**kw: cache configuration arguments. The
132 backend is configured using these arguments upon first request.
133 Subsequent requests that use the same series of configuration
134 values will use that same backend.
136 """
137 self.impl.invalidate(key, **self._get_cache_kw(kw, None))
139 def invalidate_body(self):
140 """Invalidate the cached content of the "body" method for this
141 template.
143 """
144 self.invalidate("render_body", __M_defname="render_body")
146 def invalidate_def(self, name):
147 """Invalidate the cached content of a particular ``<%def>`` within this
148 template.
150 """
152 self.invalidate("render_%s" % name, __M_defname="render_%s" % name)
154 def invalidate_closure(self, name):
155 """Invalidate a nested ``<%def>`` within this template.
157 Caching of nested defs is a blunt tool as there is no
158 management of scope -- nested defs that use cache tags
159 need to have names unique of all other nested defs in the
160 template, else their content will be overwritten by
161 each other.
163 """
165 self.invalidate(name, __M_defname=name)
167 def _get_cache_kw(self, kw, context):
168 defname = kw.pop("__M_defname", None)
169 if not defname:
170 tmpl_kw = self.template.cache_args.copy()
171 tmpl_kw.update(kw)
172 elif defname in self._def_regions:
173 tmpl_kw = self._def_regions[defname]
174 else:
175 tmpl_kw = self.template.cache_args.copy()
176 tmpl_kw.update(kw)
177 self._def_regions[defname] = tmpl_kw
178 if context and self.impl.pass_context:
179 tmpl_kw = tmpl_kw.copy()
180 tmpl_kw.setdefault("context", context)
181 return tmpl_kw
184class CacheImpl(object):
186 """Provide a cache implementation for use by :class:`.Cache`."""
188 def __init__(self, cache):
189 self.cache = cache
191 pass_context = False
192 """If ``True``, the :class:`.Context` will be passed to
193 :meth:`get_or_create <.CacheImpl.get_or_create>` as the name ``'context'``.
194 """
196 def get_or_create(self, key, creation_function, **kw):
197 r"""Retrieve a value from the cache, using the given creation function
198 to generate a new value.
200 This function *must* return a value, either from
201 the cache, or via the given creation function.
202 If the creation function is called, the newly
203 created value should be populated into the cache
204 under the given key before being returned.
206 :param key: the value's key.
207 :param creation_function: function that when called generates
208 a new value.
209 :param \**kw: cache configuration arguments.
211 """
212 raise NotImplementedError()
214 def set(self, key, value, **kw):
215 r"""Place a value in the cache.
217 :param key: the value's key.
218 :param value: the value.
219 :param \**kw: cache configuration arguments.
221 """
222 raise NotImplementedError()
224 def get(self, key, **kw):
225 r"""Retrieve a value from the cache.
227 :param key: the value's key.
228 :param \**kw: cache configuration arguments.
230 """
231 raise NotImplementedError()
233 def invalidate(self, key, **kw):
234 r"""Invalidate a value in the cache.
236 :param key: the value's key.
237 :param \**kw: cache configuration arguments.
239 """
240 raise NotImplementedError()