From 49db3f99c9f09caec8d63534b371808fbd4c2209 Mon Sep 17 00:00:00 2001
From: Mike Bayer <mike_mp@zzzcomputing.com>
Date: Wed, 11 Aug 2010 15:26:58 -0400
Subject: [PATCH] - ${} expressions embedded in tags,   such as <%foo:bar
 x="${...}">, now   allow multiline Python expressions.

---
 CHANGES           |  4 ++++
 mako/__init__.py  |  2 +-
 mako/parsetree.py |  4 ++--
 test/test_call.py | 34 +++++++++++++++++++++++++++++++---
 4 files changed, 38 insertions(+), 6 deletions(-)

diff --git a/CHANGES b/CHANGES
index 18289c4..a622408 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,10 @@
   must be referenced explicitly.
   [ticket:141]
 
+- ${} expressions embedded in tags, 
+  such as <%foo:bar x="${...}">, now 
+  allow multiline Python expressions.
+  
 - Fixed previously non-covered regular 
   expression, such that using a ${} expression 
   inside of a tag element that doesn't allow 
diff --git a/mako/__init__.py b/mako/__init__.py
index 2d13593..8914734 100644
--- a/mako/__init__.py
+++ b/mako/__init__.py
@@ -5,5 +5,5 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 
-__version__ = '0.3.4'
+__version__ = '0.3.5'
 
diff --git a/mako/parsetree.py b/mako/parsetree.py
index 577b18c..824762d 100644
--- a/mako/parsetree.py
+++ b/mako/parsetree.py
@@ -268,8 +268,8 @@ class Tag(Node):
         for key in self.attributes:
             if key in expressions:
                 expr = []
-                for x in re.split(r'(\${.+?})', self.attributes[key]):
-                    m = re.match(r'^\${(.+?)}$', x)
+                for x in re.compile(r'(\${.+?})', re.S).split(self.attributes[key]):
+                    m = re.compile(r'^\${(.+?)}$', re.S).match(x)
                     if m:
                         code = ast.PythonCode(m.group(1), **self.exception_kwargs)
                         undeclared_identifiers = undeclared_identifiers.union(
diff --git a/test/test_call.py b/test/test_call.py
index 3e6cd26..d47ec11 100644
--- a/test/test_call.py
+++ b/test/test_call.py
@@ -1,9 +1,9 @@
 from mako.template import Template
 from mako import util
-import unittest
 from util import result_lines, flatten_result
+from test import TemplateTest, eq_
 
-class CallTest(unittest.TestCase):
+class CallTest(TemplateTest):
     def test_call(self):
         t = Template("""
         <%def name="foo()">
@@ -44,6 +44,34 @@ class CallTest(unittest.TestCase):
 """)
         assert result_lines(t.render()) == ['foo calling comp1:', 'this is comp1, 5', 'foo calling body:', 'this is the body,', 'this is comp1, 6', 'this is bar']
 
+    def test_new_syntax(self):
+        """test foo:bar syntax, including multiline args and expression eval."""
+        
+        t = Template("""
+            <%def name="foo(x, y, q, z)">
+                ${x}
+                ${y}
+                ${q}
+                ${",".join("%s->%s" % (a, b) for a, b in z)}
+            </%def>
+            
+            <%self:foo x="this is x" y="${'some ' + 'y'}" q="
+                this
+                is
+                q"
+                
+                z="${[
+                (1, 2),
+                (3, 4),
+                (5, 6)
+            ]}"/>
+        """)
+        
+        eq_(
+            result_lines(t.render()),
+             ['this is x', 'some y', 'this', 'is', 'q', '1->2,3->4,5->6']
+        )
+        
     def test_ccall_caller(self):
         t = Template("""
         <%def name="outer_func()">
@@ -380,7 +408,7 @@ class CallTest(unittest.TestCase):
 """)
         assert result_lines(t.render()) == ['this is a', 'this is b', 'this is c:', "this is the body in b's call", 'the embedded "d" is:', 'this is d']
 
-class SelfCacheTest(unittest.TestCase):
+class SelfCacheTest(TemplateTest):
     """this test uses a now non-public API."""
     
     def test_basic(self):
-- 
GitLab