Mercurial > genshi > mirror
changeset 604:416e46209da1 trunk
Fix bug that slipped into [717]: the code of a `py:with` directive was not being compiled with AST transformations applied.
author | cmlenz |
---|---|
date | Thu, 23 Aug 2007 12:22:57 +0000 |
parents | 80e346366c83 |
children | d0345c64da65 |
files | genshi/template/directives.py genshi/template/eval.py genshi/template/tests/directives.py |
diffstat | 3 files changed, 31 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/genshi/template/directives.py +++ b/genshi/template/directives.py @@ -23,7 +23,8 @@ from genshi.path import Path from genshi.template.base import TemplateRuntimeError, TemplateSyntaxError, \ EXPR, _apply_directives -from genshi.template.eval import Expression, Suite, _parse +from genshi.template.eval import Expression, Suite, ExpressionASTTransformer, \ + _parse __all__ = ['AttrsDirective', 'ChooseDirective', 'ContentDirective', 'DefDirective', 'ForDirective', 'IfDirective', 'MatchDirective', @@ -697,7 +698,8 @@ Directive.__init__(self, None, template, namespaces, lineno, offset) try: self.suite = Suite(value, template.filepath, lineno, - lookup=template.lookup) + lookup=template.lookup, + xform=ExpressionASTTransformer) except SyntaxError, err: err.msg += ' in expression "%s" of "%s" directive' % (value, self.tagname)
--- a/genshi/template/eval.py +++ b/genshi/template/eval.py @@ -38,7 +38,8 @@ """Abstract base class for the `Expression` and `Suite` classes.""" __slots__ = ['source', 'code', 'ast', '_globals'] - def __init__(self, source, filename=None, lineno=-1, lookup='lenient'): + def __init__(self, source, filename=None, lineno=-1, lookup='lenient', + xform=None): """Create the code object, either from a string, or from an AST node. :param source: either a string containing the source code, or an AST @@ -49,6 +50,9 @@ :param lookup: the lookup class that defines how variables are looked up in the context. Can be either `LenientLookup` (the default), `StrictLookup`, or a custom lookup class + :param xform: the AST transformer that should be applied to the code; + if `None`, the appropriate transformation is chosen + depending on the mode """ if isinstance(source, basestring): self.source = source @@ -64,7 +68,7 @@ self.ast = node self.code = _compile(node, self.source, mode=self.mode, - filename=filename, lineno=lineno) + filename=filename, lineno=lineno, xform=xform) if lookup is None: lookup = LenientLookup elif isinstance(lookup, basestring): @@ -374,8 +378,11 @@ source = '\xef\xbb\xbf' + source.encode('utf-8') return parse(source, mode) -def _compile(node, source=None, mode='eval', filename=None, lineno=-1): - xform = {'eval': ExpressionASTTransformer}.get(mode, TemplateASTTransformer) +def _compile(node, source=None, mode='eval', filename=None, lineno=-1, + xform=None): + if xform is None: + xform = {'eval': ExpressionASTTransformer}.get(mode, + TemplateASTTransformer) tree = xform().visit(node) if isinstance(filename, unicode): # unicode file names not allowed for code objects
--- a/genshi/template/tests/directives.py +++ b/genshi/template/tests/directives.py @@ -1016,6 +1016,22 @@ here are two semicolons: ;; </div>""", str(tmpl.generate())) + def test_ast_transformation(self): + """ + Verify that the usual template expression AST transformations are + applied despite the code being compiled to a `Suite` object. + """ + tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> + <span py:with="bar=foo.bar"> + $bar + </span> + </div>""") + self.assertEqual("""<div> + <span> + 42 + </span> + </div>""", str(tmpl.generate(foo={'bar': 42}))) + def test_unicode_expr(self): tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> <span py:with="weeks=(u'一', u'二', u'三', u'四', u'五', u'六', u'日')">