# HG changeset patch # User cmlenz # Date 1236244603 0 # Node ID aa274188b77ac3ccbc513796497d514a68f47187 # Parent 1d7b582b09a4ec14dfe9839ed58a0587a024399b Fix handling of function arguments with default values in template code, applying patch by Scott Wilson plus an additional fix. Closes #292. diff --git a/genshi/template/astutil.py b/genshi/template/astutil.py --- 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(', ') diff --git a/genshi/template/eval.py b/genshi/template/eval.py --- 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): diff --git a/genshi/template/tests/eval.py b/genshi/template/tests/eval.py --- 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():