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()
Copyright (C) 2012-2017 Edgewall Software