aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGES2
-rw-r--r--lib/mako/codegen.py17
-rw-r--r--test/cache.py32
3 files changed, 44 insertions, 7 deletions
diff --git a/CHANGES b/CHANGES
index f160bc5..c568595 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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("""
<%!