diff --git a/doc/build/content/caching.txt b/doc/build/content/caching.txt index 7e018d779b7bd20c50ba09c5482bc446880493e3..7e0c0b36cb3655aed0915ad546a1ebbbcde6f992 100644 --- a/doc/build/content/caching.txt +++ b/doc/build/content/caching.txt @@ -32,11 +32,11 @@ The options available are: In the case of the `memcached` type, this attribute is required and it's used to store the lock files. * cache_key - the "key" used to uniquely identify this content in the cache. the total namespace of keys within the cache is local to the current template, and the default value of "key" is the name of the def which is storing its data. It is an evaluable tag, so you can put a Python expression to calculate the value of the key on the fly. For example, heres a page that caches any page which inherits from it, based on the filename of the calling template: - <%page cached="True" cache_key="${self.filename}"/> + <%page cached="True" cache_key="${self.filename}"/> - ${next.body()} + ${next.body()} - ## rest of template + ## rest of template ### Accessing the Cache {@name=accessing} @@ -60,4 +60,5 @@ More commonly the `cache` object is used to invalidate cached sections programma template.cache.invalidate_def('somedef') # invalidate an arbitrary key - template.cache.invalidate('somekey') \ No newline at end of file + template.cache.invalidate('somekey') + \ No newline at end of file diff --git a/lib/mako/cache.py b/lib/mako/cache.py index a539523f72b3a1b73e0f4223d45ea8c169281500..20ceba7444821e74bfa194818369adc45df0d8be 100644 --- a/lib/mako/cache.py +++ b/lib/mako/cache.py @@ -16,7 +16,7 @@ class Cache(object): self.starttime = starttime if container is not None: self.context = container.ContainerContext() - self._values = {} + self.def_regions = {} def put(self, key, value, **kwargs): c = self._get_container(key, **kwargs) @@ -31,29 +31,30 @@ class Cache(object): else: return None - def invalidate(self, key, **kwargs): - c = self._get_container(key, **kwargs) + def invalidate(self, key, defname, **kwargs): + c = self._get_container(key, defname, **kwargs) if c: c.clear_value() def invalidate_body(self): - self.invalidate('render_body') + self.invalidate('render_body', 'render_body') def invalidate_def(self, name): - self.invalidate('render_%s' % name) + self.invalidate('render_%s' % name, 'render_%s' % name) def invalidate_closure(self, name): - self.invalidate(name) + self.invalidate(name, name) - def _get_container(self, key, **kwargs): + def _get_container(self, key, defname, **kwargs): if not container: raise exceptions.RuntimeException("the Beaker package is required to use cache functionality.") - if kwargs: - type = kwargs.pop('type', 'memory') - self._values[key] = k = container.Value(key, self.context, self.id, clsmap[type], starttime=self.starttime, **kwargs) - return k + type = kwargs.pop('type', None) + if not type: + type = self.def_regions.get(defname, 'memory') else: - return self._values.get(key, None) + self.def_regions[defname] = type + + return container.Value(key, self.context, self.id, clsmap[type], starttime=self.starttime, **kwargs) diff --git a/lib/mako/codegen.py b/lib/mako/codegen.py index 3b1d531ef8543a82b0c9a5ad5b33cc13c0850cc5..0f1be999c3511ffbc7ce903144054337870f2cae 100644 --- a/lib/mako/codegen.py +++ b/lib/mako/codegen.py @@ -11,7 +11,7 @@ import re from mako.pygen import PythonPrinter from mako import util, ast, parsetree, filters -MAGIC_NUMBER = 4 +MAGIC_NUMBER = 5 def compile(node, uri, filename=None, default_filters=None, buffer_filters=None, imports=None, source_encoding=None, generate_unicode=True): @@ -428,13 +428,13 @@ class _GenerateRenderMethod(object): self.write_variable_declares(identifiers, toplevel=toplevel, limit=node_or_pagetag.undeclared_identifiers()) if buffered: - s = "context.get('local').get_cached(%s, %screatefunc=lambda:__M_%s(%s))" % (cachekey, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ','.join(pass_args)) + s = "context.get('local').get_cached(%s, defname=%r, %screatefunc=lambda:__M_%s(%s))" % (cachekey, name, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ','.join(pass_args)) # apply buffer_filters s = self.create_filter_callable(self.compiler.buffer_filters, s, False) self.printer.writelines("return " + s,None) else: self.printer.writelines( - "__M_writer(context.get('local').get_cached(%s, %screatefunc=lambda:__M_%s(%s)))" % (cachekey, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ','.join(pass_args)), + "__M_writer(context.get('local').get_cached(%s, defname=%r, %screatefunc=lambda:__M_%s(%s)))" % (cachekey, name, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ','.join(pass_args)), "return ''", None ) diff --git a/test/cache.py b/test/cache.py index cca53b67157a401e0275fe22dee268fad9913f6f..80f6416e671ddafe38759ca393ad33ebc90869df 100644 --- a/test/cache.py +++ b/test/cache.py @@ -19,6 +19,7 @@ class MockCache(object): self.key = key self.kwargs = kwargs.copy() self.kwargs.pop('createfunc', None) + self.kwargs.pop('defname', None) return self.realcache.get(key, **kwargs) class CacheTest(unittest.TestCase): @@ -363,7 +364,6 @@ class CacheTest(unittest.TestCase): </%def> ${foo()} ${bar()} """) - assert result_lines(t.render(x=1)) == ["foo: 1", "bar: 1"] assert result_lines(t.render(x=2)) == ["foo: 1", "bar: 1"] t.cache.invalidate_def('foo')