Mercurial > genshi > mirror
diff genshi/template/directives.py @ 601:59fbd7586454 trunk
Simplify implementation of `py:with` directive by compiling to a `Suite`, instead of manually breaking up the statement and compiling each part to an `Expression`. Also, the first line of code in a `Suite` is now stored as the "function name" of the bytecode, so that it shows up in tracebacks.
author | cmlenz |
---|---|
date | Wed, 22 Aug 2007 21:50:46 +0000 |
parents | b3dc05d88751 |
children | d7b957e92ea9 |
line wrap: on
line diff
--- a/genshi/template/directives.py +++ b/genshi/template/directives.py @@ -19,7 +19,7 @@ from genshi.path import Path from genshi.template.base import TemplateRuntimeError, TemplateSyntaxError, \ EXPR, _apply_directives -from genshi.template.eval import Expression, _parse +from genshi.template.eval import Expression, Suite, _parse __all__ = ['AttrsDirective', 'ChooseDirective', 'ContentDirective', 'DefDirective', 'ForDirective', 'IfDirective', 'MatchDirective', @@ -680,30 +680,26 @@ <span>42 7 52</span> </div> """ - __slots__ = ['vars'] + __slots__ = ['suite'] def __init__(self, value, template, namespaces=None, lineno=-1, offset=-1): Directive.__init__(self, None, template, namespaces, lineno, offset) - self.vars = [] - value = value.strip() try: - ast = _parse(value, 'exec').node - for node in ast.nodes: - if isinstance(node, compiler.ast.Discard): - continue - elif not isinstance(node, compiler.ast.Assign): - raise TemplateSyntaxError('only assignment allowed in ' - 'value of the "with" directive', - template.filepath, lineno, offset) - self.vars.append(([_assignment(n) for n in node.nodes], - Expression(node.expr, template.filepath, - lineno, lookup=template.lookup))) + self.suite = Suite(value, template.filepath, lineno, + lookup=template.lookup) except SyntaxError, err: err.msg += ' in expression "%s" of "%s" directive' % (value, self.tagname) raise TemplateSyntaxError(err, template.filepath, lineno, offset + (err.offset or 0)) + for node in self.suite.ast.node.nodes: + if not isinstance(node, (compiler.ast.Discard, + compiler.ast.Assign)): + raise TemplateSyntaxError('only assignment allowed in value of ' + 'the "with" directive', + template.filepath, lineno, offset) + def attach(cls, template, stream, value, namespaces, pos): if type(value) is dict: value = value.get('vars') @@ -714,10 +710,7 @@ def __call__(self, stream, ctxt, directives): frame = {} ctxt.push(frame) - for targets, expr in self.vars: - value = expr.evaluate(ctxt) - for assign in targets: - assign(frame, value) + self.suite.execute(ctxt) for event in _apply_directives(stream, ctxt, directives): yield event ctxt.pop()