summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-03-08 16:02:05 -0800
committerMike Bayer <mike_mp@zzzcomputing.com>2012-03-08 16:02:05 -0800
commit936a524263b90071d601b09a63f3c86117769b61 (patch)
tree579e966b009b9b0aa1436cf0bc2754abe76220f8
parent2f022a271212b220519305649e6a8490cf4399ff (diff)
downloadmako-936a524263b90071d601b09a63f3c86117769b61.tar.gz
- [bug] Fixed endless recursion bug when
nesting multiple def-calls with content. Thanks to Jeff Dairiki. [ticket:186]
-rw-r--r--CHANGES4
-rw-r--r--mako/codegen.py8
-rw-r--r--mako/runtime.py6
-rw-r--r--test/test_call.py11
4 files changed, 24 insertions, 5 deletions
diff --git a/CHANGES b/CHANGES
index 4783699..2d3dabe 100644
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,10 @@
to filehandles being implicitly closed.
[ticket:182]
+- [bug] Fixed endless recursion bug when
+ nesting multiple def-calls with content.
+ Thanks to Jeff Dairiki. [ticket:186]
+
0.6.2
- [bug] The ${{"foo":"bar"}} parsing issue is fixed!!
The legendary Eevee has slain the dragon!
diff --git a/mako/codegen.py b/mako/codegen.py
index 2e15124..704330c 100644
--- a/mako/codegen.py
+++ b/mako/codegen.py
@@ -231,7 +231,8 @@ class _GenerateRenderMethod(object):
self.printer.writelines(
"def %s(%s):" % (name, ','.join(args)),
- "context.caller_stack._push_frame()",
+ # push new frame, assign current frame to __M_caller
+ "__M_caller = context.caller_stack._push_frame()",
"try:"
)
if buffered or filtered or cached:
@@ -516,7 +517,8 @@ class _GenerateRenderMethod(object):
buffered = eval(node.attributes.get('buffered', 'False'))
cached = eval(node.attributes.get('cached', 'False'))
self.printer.writelines(
- "context.caller_stack._push_frame()",
+ # push new frame, assign current frame to __M_caller
+ "__M_caller = context.caller_stack._push_frame()",
"try:"
)
if buffered or filtered or cached:
@@ -848,8 +850,6 @@ class _GenerateRenderMethod(object):
)
self.printer.writelines(
- # get local reference to current caller, if any
- "__M_caller = context.caller_stack._get_caller()",
# push on caller for nested call
"context.caller_stack.nextcaller = "
"runtime.Namespace('caller', context, callables=ccall(__M_caller))",
diff --git a/mako/runtime.py b/mako/runtime.py
index 65c03e1..b56fa67 100644
--- a/mako/runtime.py
+++ b/mako/runtime.py
@@ -158,12 +158,16 @@ class CallerStack(list):
def __nonzero__(self):
return self._get_caller() and True or False
def _get_caller(self):
+ # this method can be removed once
+ # codegen MAGIC_NUMBER moves past 7
return self[-1]
def __getattr__(self, key):
return getattr(self._get_caller(), key)
def _push_frame(self):
- self.append(self.nextcaller or None)
+ frame = self.nextcaller or None
+ self.append(frame)
self.nextcaller = None
+ return frame
def _pop_frame(self):
self.nextcaller = self.pop()
diff --git a/test/test_call.py b/test/test_call.py
index 5f13e95..0bb6079 100644
--- a/test/test_call.py
+++ b/test/test_call.py
@@ -385,6 +385,17 @@ class CallTest(TemplateTest):
""")
assert result_lines(t.render()) == ['this is a', 'this is b', 'this is c:', "this is the body in b's call"]
+ def test_composed_def(self):
+ t = Template("""
+ <%def name="f()"><f>${caller.body()}</f></%def>
+ <%def name="g()"><g>${caller.body()}</g></%def>
+ <%def name="fg()">
+ <%self:f><%self:g>${caller.body()}</%self:g></%self:f>
+ </%def>
+ <%self:fg>fgbody</%self:fg>
+ """)
+ assert result_lines(t.render()) == ['<f><g>fgbody</g></f>']
+
def test_regular_defs(self):
t = Template("""
<%!