- [bug] Fixed the "filter" attribute of the <%text> tag so that it pulls locally specified identifiers from the context the same way as that of <%block> and <%filter>.
diff --git a/CHANGES b/CHANGES index afb82d4..c9e899e 100644 --- a/CHANGES +++ b/CHANGES
@@ -6,6 +6,11 @@ - [bug] Fixed Py3K bug in the Babel extension. +- [bug] Fixed the "filter" attribute of the + <%text> tag so that it pulls locally specified + identifiers from the context the same + way as that of <%block> and <%filter>. + 0.7.2 - [bug] Fixed regression in 0.7.1 where AST parsing for Py2.4 was broken.
diff --git a/mako/codegen.py b/mako/codegen.py index 3cec0ee..6c54892 100644 --- a/mako/codegen.py +++ b/mako/codegen.py
@@ -153,7 +153,7 @@ inherit = [] namespaces = {} module_code = [] - encoding =[None] + encoding = [None] self.compiler.pagetag = None @@ -315,7 +315,7 @@ "except KeyError:", "_mako_generate_namespaces(context)", "return context.namespaces[(__name__, name)]", - None,None + None, None ) self.printer.writeline("def _mako_generate_namespaces(context):") @@ -1115,7 +1115,7 @@ % (node.name, ), **node.exception_kwargs) for ident in node.undeclared_identifiers(): - if ident != 'context' and\ + if ident != 'context' and \ ident not in self.declared.union(self.locally_declared): self.undeclared.add(ident) @@ -1129,6 +1129,12 @@ for n in node.nodes: n.accept_visitor(self) + def visitTextTag(self, node): + for ident in node.undeclared_identifiers(): + if ident != 'context' and \ + ident not in self.declared.union(self.locally_declared): + self.undeclared.add(ident) + def visitIncludeTag(self, node): self.check_declared(node)
diff --git a/mako/parsetree.py b/mako/parsetree.py index ecd8242..b5247f1 100644 --- a/mako/parsetree.py +++ b/mako/parsetree.py
@@ -393,6 +393,13 @@ attributes.get('filter', ''), **self.exception_kwargs) + def undeclared_identifiers(self): + return self.filter_args.\ + undeclared_identifiers.\ + difference(filters.DEFAULT_ESCAPES.keys()).union( + self.expression_undeclared_identifiers + ) + class DefTag(Tag): __keyword__ = 'def' @@ -405,11 +412,11 @@ keyword, attributes, expressions, - ('name','filter', 'decorator'), + ('name', 'filter', 'decorator'), ('name',), **kwargs) name = attributes['name'] - if re.match(r'^[\w_]+$',name): + if re.match(r'^[\w_]+$', name): raise exceptions.CompileException( "Missing parenthesis in %def", **self.exception_kwargs)
diff --git a/test/test_filters.py b/test/test_filters.py index 684705d..d831b71 100644 --- a/test/test_filters.py +++ b/test/test_filters.py
@@ -28,17 +28,17 @@ ${x | trim} """) assert flatten_result(t.render(x=5)) == "5" - + def test_quoting(self): t = Template(""" foo ${bar | h} """) - + eq_( flatten_result(t.render(bar="<'some bar'>")), "foo <'some bar'>" ) - + @skip_if(lambda: util.py3k) def test_quoting_non_unicode(self): t = Template(""" @@ -50,8 +50,8 @@ flatten_result(t.render(bar="<'привет'>")), "foo <'привет'>" ) - - + + def test_def(self): t = Template(""" <%def name="foo()" filter="myfilter"> @@ -61,7 +61,7 @@ """) eq_( - flatten_result(t.render(x="this is x", + flatten_result(t.render(x="this is x", myfilter=lambda t: "MYFILTER->%s<-MYFILTER" % t)), "MYFILTER-> this is foo <-MYFILTER" ) @@ -75,7 +75,7 @@ """) assert t.render().strip()=="trim this string: some string to trim continue" - + def test_import_2(self): t = Template(""" trim this string: ${" some string to trim " | filters.trim} continue\ @@ -89,18 +89,18 @@ """, default_filters=['decode.utf8']) #print t.code assert t.render_unicode(x="voix m’a réveillé").strip() == u"some stuff.... voix m’a réveillé" - + def test_custom_default(self): t = Template(""" <%! def myfilter(x): return "->" + x + "<-" %> - + hi ${'there'} """, default_filters=['myfilter']) assert t.render().strip()=="hi ->there<-" - + def test_global(self): t = Template(""" <%page expression_filter="h"/> @@ -135,6 +135,20 @@ ["MYTEXT", "some text"] ) + def test_text_via_context(self): + t = Template(""" + <%text filter="myfilter"> + some text + </%text> + """) + def myfilter(text): + return "MYTEXT" + text + eq_( + result_lines(t.render(myfilter=myfilter)), + ["MYTEXT", "some text"] + ) + + def test_nflag(self): t = Template(""" ${"<tag>this is html</tag>" | n} @@ -152,7 +166,7 @@ ${"<tag>this is html</tag>" | n, h} """) assert t.render().strip() == "<tag>this is html</tag>" - + def test_non_expression(self): t = Template(""" <%! @@ -161,7 +175,7 @@ def b(text): return "this is b" %> - + ${foo()} <%def name="foo()" buffered="True"> this is text @@ -176,7 +190,7 @@ def b(text): return "this is b" %> - + ${'hi'} ${foo()} <%def name="foo()" buffered="True"> @@ -199,7 +213,7 @@ else: return "this is b" %> - + ${'hi'} ${foo()} <%def name="foo()" buffered="True"> @@ -215,7 +229,7 @@ def b(text): return "this is b" %> - + ${foo()} ${bar()} <%def name="foo()" filter="b"> @@ -227,19 +241,19 @@ """, buffer_filters=['a']) assert flatten_result(t.render()) == "this is b this is a" - + def test_builtins(self): t = Template(""" ${"this is <text>" | h} """) assert flatten_result(t.render()) == "this is <text>" - + t = Template(""" http://foo.com/arg1=${"hi! this is a string." | u} """) assert flatten_result(t.render()) == "http://foo.com/arg1=hi%21+this+is+a+string." -class BufferTest(unittest.TestCase): +class BufferTest(unittest.TestCase): def test_buffered_def(self): t = Template(""" <%def name="foo()" buffered="True"> @@ -271,7 +285,7 @@ template = Template(""" <%def name="a()"> this is a - <% + <% raise TypeError("hi") %> </%def> @@ -285,7 +299,7 @@ assert False except TypeError: assert True - + def test_buffered_exception(self): template = Template(""" <%def name="a()" buffered="True"> @@ -293,16 +307,16 @@ raise TypeError("hi") %> </%def> - + ${a()} - -""") + +""") try: print template.render() assert False except TypeError: assert True - + def test_capture_ccall(self): t = Template(""" <%def name="foo()"> @@ -316,7 +330,7 @@ ccall body </%call> """) - + #print t.render() assert flatten_result(t.render()) == "this is foo. body: ccall body" - +