diff options
-rw-r--r-- | CHANGES | 2 | ||||
-rw-r--r-- | lib/mako/codegen.py | 17 | ||||
-rw-r--r-- | test/cache.py | 32 |
3 files changed, 44 insertions, 7 deletions
@@ -1,3 +1,5 @@ +- got defs-within-defs to be cacheable + 0.1.3 - ***Small Syntax Change*** - the single line comment character is now *two* hash signs, i.e. "## this is a comment". This avoids a common diff --git a/lib/mako/codegen.py b/lib/mako/codegen.py index 285e392..0621e27 100644 --- a/lib/mako/codegen.py +++ b/lib/mako/codegen.py @@ -312,7 +312,7 @@ class _GenerateRenderMethod(object): buffered = eval(node.attributes.get('buffered', 'False')) cached = eval(node.attributes.get('cached', 'False')) if buffered or filtered or cached: - printer.writelines( + self.printer.writelines( "context.push_buffer()", "try:" ) @@ -329,7 +329,7 @@ class _GenerateRenderMethod(object): self.write_def_finish(node, buffered, filtered, cached) self.printer.writeline(None) if cached: - self.write_cache_decorator(node, node.name, False, identifiers) + self.write_cache_decorator(node, node.name, False, identifiers, inline=True) def write_def_finish(self, node, buffered, filtered, cached): """write the end section of a rendering function, either outermost or inline. @@ -352,7 +352,7 @@ class _GenerateRenderMethod(object): self.printer.writeline("context.write(%s)" % s) self.printer.writeline("return ''") - def write_cache_decorator(self, node_or_pagetag, name, buffered, identifiers): + def write_cache_decorator(self, node_or_pagetag, name, buffered, identifiers, inline=False): """write a post-function decorator to replace a rendering callable with a cached version of itself.""" self.printer.writeline("__%s = %s" % (name, name)) cachekey = node_or_pagetag.parsed_attributes.get('cache_key', repr(name)) @@ -372,18 +372,23 @@ class _GenerateRenderMethod(object): cacheargs[arg[1]] == int(eval(val)) else: cacheargs[arg[1]] = val + + if inline: + ctx_arg = "" + else: + ctx_arg = "context, " - self.printer.writeline("def %s(context, *args, **kwargs):" % name) + self.printer.writeline("def %s(%s*args, **kwargs):" % (name, ctx_arg)) self.write_variable_declares(identifiers, limit=node_or_pagetag.undeclared_identifiers()) if buffered: self.printer.writelines( - "return context.get('local').get_cached(%s, %screatefunc=lambda:__%s(context, *args, **kwargs))" % (cachekey, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name), + "return context.get('local').get_cached(%s, %screatefunc=lambda:__%s(%s*args, **kwargs))" % (cachekey, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ctx_arg), None ) else: self.printer.writelines( - "context.write(context.get('local').get_cached(%s, %screatefunc=lambda:__%s(context, *args, **kwargs)))" % (cachekey, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name), + "context.write(context.get('local').get_cached(%s, %screatefunc=lambda:__%s(%s*args, **kwargs)))" % (cachekey, ''.join(["%s=%s, " % (k,v) for k, v in cacheargs.iteritems()]), name, ctx_arg), "return ''", None ) diff --git a/test/cache.py b/test/cache.py index dd5a5fd..b9f3e71 100644 --- a/test/cache.py +++ b/test/cache.py @@ -16,7 +16,7 @@ class MockCache(object): return self.realcache.get(key, **kwargs) class CacheTest(unittest.TestCase): - def test_component(self): + def test_def(self): t = Template(""" <%! callcount = [0] @@ -42,6 +42,36 @@ class CacheTest(unittest.TestCase): ] assert m.kwargs == {} + def test_nested_def(self): + t = Template(""" + <%! + callcount = [0] + %> + <%def name="foo()"> + <%def name="bar()" cached="True"> + this is foo + <% + callcount[0] += 1 + %> + </%def> + ${bar()} + </%def> + + ${foo()} + ${foo()} + ${foo()} + callcount: ${callcount} +""") + m = self._install_mock_cache(t) + print t.code + assert result_lines(t.render()) == [ + 'this is foo', + 'this is foo', + 'this is foo', + 'callcount: [1]', + ] + assert m.kwargs == {} + def test_page(self): t = Template(""" <%! |