diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-03-08 16:02:05 -0800 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-03-08 16:02:05 -0800 |
commit | 936a524263b90071d601b09a63f3c86117769b61 (patch) | |
tree | 579e966b009b9b0aa1436cf0bc2754abe76220f8 | |
parent | 2f022a271212b220519305649e6a8490cf4399ff (diff) | |
download | mako-936a524263b90071d601b09a63f3c86117769b61.tar.gz |
- [bug] Fixed endless recursion bug when
nesting multiple def-calls with content.
Thanks to Jeff Dairiki. [ticket:186]
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | mako/codegen.py | 8 | ||||
-rw-r--r-- | mako/runtime.py | 6 | ||||
-rw-r--r-- | test/test_call.py | 11 |
4 files changed, 24 insertions, 5 deletions
@@ -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(""" <%! |