changeset 802:aa274188b77a

Fix handling of function arguments with default values in template code, applying patch by Scott Wilson plus an additional fix. Closes #292.
author cmlenz
date Thu, 05 Mar 2009 09:16:43 +0000
parents 1d7b582b09a4
children 92b9b647e1fe
files genshi/template/astutil.py genshi/template/eval.py genshi/template/tests/eval.py
diffstat 3 files changed, 57 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/genshi/template/astutil.py
+++ b/genshi/template/astutil.py
@@ -106,18 +106,19 @@
         return self.visit(node.body)
 
     # arguments = (expr* args, identifier? vararg,
-    #                 identifier? kwarg, expr* defaults)
+    #              identifier? kwarg, expr* defaults)
     def visit_arguments(self, node):
         first = True
+        no_default_count = len(node.args) - len(node.defaults)
         for i, arg in enumerate(node.args):
             if not first:
                 self._write(', ')
             else:
                 first = False
             self.visit(arg)
-            if i < len(node.defaults):
+            if i >= no_default_count:
                 self._write('=')
-                self.visit(node.defaults[i])
+                self.visit(node.defaults[i - no_default_count])
         if getattr(node, 'vararg', None):
             if not first:
                 self._write(', ')
--- a/genshi/template/eval.py
+++ b/genshi/template/eval.py
@@ -494,10 +494,10 @@
                     _process(node)
         for arg in node.args:
             _process(arg)
-        if getattr(node, 'varargs', None):
-            arguments.add(node.args.varargs)
-        if getattr(node, 'kwargs', None):
-            arguments.add(node.args.kwargs)
+        if hasattr(node, 'vararg'):
+            arguments.add(node.vararg)
+        if hasattr(node, 'kwarg'):
+            arguments.add(node.kwarg)
         return arguments
 
     def visit_Str(self, node):
--- a/genshi/template/tests/eval.py
+++ b/genshi/template/tests/eval.py
@@ -505,6 +505,55 @@
         suite.execute(data)
         self.assertEqual(['foo', 'bar'], data['values'])
 
+    def test_def_some_defaults(self):
+        suite = Suite("""
+def difference(v1, v2=10):
+    return v1 - v2
+x = difference(20, 19)
+y = difference(20)
+""")
+        data = {}
+        suite.execute(data)
+        self.assertEqual(1, data['x'])
+        self.assertEqual(10, data['y'])
+
+    def test_def_all_defaults(self):
+        suite = Suite("""
+def difference(v1=100, v2=10):
+    return v1 - v2
+x = difference(20, 19)
+y = difference(20)
+z = difference()
+""")
+        data = {}
+        suite.execute(data)
+        self.assertEqual(1, data['x'])
+        self.assertEqual(10, data['y'])
+        self.assertEqual(90, data['z'])
+
+    def test_def_vararg(self):
+        suite = Suite("""
+def mysum(*others):
+    rv = 0
+    for n in others:
+        rv = rv + n
+    return rv
+x = mysum(1, 2, 3)
+""")
+        data = {}
+        suite.execute(data)
+        self.assertEqual(6, data['x'])
+
+    def test_def_kwargs(self):
+        suite = Suite("""
+def smash(**kw):
+    return [''.join(i) for i in kw.items()]
+x = smash(foo='abc', bar='def')
+""")
+        data = {}
+        suite.execute(data)
+        self.assertEqual(['fooabc', 'bardef'], data['x'])
+
     def test_def_nested(self):
         suite = Suite("""
 def doit():
Copyright (C) 2012-2017 Edgewall Software