changeset 968:2ed9827596a4 trunk

Update genshi.template AST handling to support Python 3.4 (see #537).
author hodgestar
date Sat, 29 Dec 2012 19:31:41 +0000
parents 19ac5d8fd96c
children b839b6c91dbe
files genshi/template/astutil.py genshi/template/tests/eval.py
diffstat 2 files changed, 64 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/genshi/template/astutil.py
+++ b/genshi/template/astutil.py
@@ -281,20 +281,28 @@
             self._change_indent(-1)
 
     # With(expr context_expr, expr? optional_vars, stmt* body)
+    # With(withitem* items, stmt* body) in Python >= 3.3
     def visit_With(self, node):
         self._new_line()
         self._write('with ')
-        self.visit(node.context_expr)
-        if getattr(node, 'optional_vars', None):
-            self._write(' as ')
-            self.visit(node.optional_vars)
+        items = getattr(node, 'items', None)
+        first = True
+        if items is None:
+            items = [node]
+        for item in items:
+            if not first:
+                self._write(', ')
+            first = False
+            self.visit(item.context_expr)
+            if getattr(item, 'optional_vars', None):
+                self._write(' as ')
+                self.visit(item.optional_vars)
         self._write(':')
         self._change_indent(1)
         for statement in node.body:
             self.visit(statement)
         self._change_indent(-1)
 
-
     if IS_PYTHON2:
         # Raise(expr? type, expr? inst, expr? tback)
         def visit_Raise(self, node):
@@ -379,6 +387,33 @@
                 self.visit(statement)
             self._change_indent(-1)
 
+    # New in Py3.3
+    # Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
+    def visit_Try(self, node):
+        self._new_line()
+        self._write('try:')
+        self._change_indent(1)
+        for statement in node.body:
+            self.visit(statement)
+        self._change_indent(-1)
+        if getattr(node, 'handlers', None):
+            for handler in node.handlers:
+                self.visit(handler)
+        self._new_line()
+        if getattr(node, 'orelse', None):
+            self._write('else:')
+            self._change_indent(1)
+            for statement in node.orelse:
+                self.visit(statement)
+            self._change_indent(-1)
+        if getattr(node, 'finalbody', None):
+            self._new_line()
+            self._write('finally:')
+            self._change_indent(1)
+            for statement in node.finalbody:
+                self.visit(statement)
+            self._change_indent(-1)
+
     # Assert(expr test, expr? msg)
     def visit_Assert(self, node):
         self._new_line()
@@ -766,6 +801,7 @@
     visit_Raise = _clone
     visit_TryExcept = _clone
     visit_TryFinally = _clone
+    visit_Try = _clone
     visit_Assert = _clone
     visit_ExceptHandler = _clone
 
--- a/genshi/template/tests/eval.py
+++ b/genshi/template/tests/eval.py
@@ -859,6 +859,29 @@
             suite.execute(d)
             self.assertEqual([0, 3, 4], d['results'])
 
+    if sys.version_info >= (3, 3):
+        def test_with_statement_with_multiple_items(self):
+            fd, path = mkstemp()
+            f = os.fdopen(fd, "w")
+            try:
+                f.write('foo\n')
+                f.seek(0)
+                f.close()
+
+                d = {'path': path}
+                suite = Suite("""from __future__ import with_statement
+lines = []
+with open(path) as file1, open(path) as file2:
+    for line in file1:
+        lines.append(line)
+    for line in file2:
+        lines.append(line)
+""")
+                suite.execute(d)
+                self.assertEqual(['foo\n', 'foo\n'], d['lines'])
+            finally:
+                os.remove(path)
+
 
 def suite():
     suite = unittest.TestSuite()
Copyright (C) 2012-2017 Edgewall Software