changeset 1024:a5e09a7ba12d trunk

Add support for kwonlyargs and kw_defaults attributes of AST argument nodes.
author hodgestar
date Sun, 16 Feb 2014 19:36:21 +0000
parents 2036193f89e7
children 8f5ead39e537
files genshi/template/astutil.py genshi/template/eval.py genshi/template/tests/eval.py
diffstat 3 files changed, 47 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/genshi/template/astutil.py
+++ b/genshi/template/astutil.py
@@ -111,32 +111,35 @@
     # arguments = (arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults,
     #              arg? 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(', ')
+        def write_possible_comma():
+            if _first[0]:
+                _first[0] = False
             else:
-                first = False
-            self.visit(arg)
-            if i >= no_default_count:
-                self._write('=')
-                self.visit(node.defaults[i - no_default_count])
+                self._write(', ')
+        _first = [True]
+
+        def write_args(args, defaults):
+            no_default_count = len(args) - len(defaults)
+            for i, arg in enumerate(args):
+                write_possible_comma()
+                self.visit(arg)
+                default_idx = i - no_default_count
+                if default_idx >= 0 and defaults[default_idx] is not None:
+                    self._write('=')
+                    self.visit(defaults[i - no_default_count])
+
+        write_args(node.args, node.defaults)
         if getattr(node, 'vararg', None):
-            if not first:
-                self._write(', ')
-            else:
-                first = False
+            write_possible_comma()
             self._write('*')
             if isstring(node.vararg):
                 self._write(node.vararg)
             else:
                 self.visit(node.vararg)
+        if getattr(node, 'kwonlyargs', None):
+            write_args(node.kwonlyargs, node.kw_defaults)
         if getattr(node, 'kwarg', None):
-            if not first:
-                self._write(', ')
-            else:
-                first = False
+            write_possible_comma()
             self._write('**')
             if isstring(node.kwarg):
                 self._write(node.kwarg)
--- a/genshi/template/eval.py
+++ b/genshi/template/eval.py
@@ -514,6 +514,9 @@
         if hasattr(node, 'args'):
             for arg in node.args:
                 self._process(names, arg)
+            if hasattr(node, 'kwonlyargs'):
+                for arg in node.kwonlyargs:
+                    self._process(names, arg)
             if hasattr(node, 'vararg'):
                 self._process(names, node.vararg)
             if hasattr(node, 'kwarg'):
--- a/genshi/template/tests/eval.py
+++ b/genshi/template/tests/eval.py
@@ -590,6 +590,29 @@
         suite.execute(data)
         self.assertEqual(['bardef', 'fooabc'], sorted(data['x']))
 
+    if not IS_PYTHON2:
+        def test_def_kwonlyarg(self):
+            suite = Suite("""
+def kwonly(*args, k):
+    return k
+x = kwonly(k="foo")
+""")
+            data = {}
+            suite.execute(data)
+            self.assertEqual("foo", data['x'])
+
+        def test_def_kwonlyarg_with_default(self):
+            suite = Suite("""
+def kwonly(*args, k="bar"):
+    return k
+x = kwonly(k="foo")
+y = kwonly()
+""")
+            data = {}
+            suite.execute(data)
+            self.assertEqual("foo", data['x'])
+            self.assertEqual("bar", data['y'])
+
     def test_def_nested(self):
         suite = Suite("""
 def doit():
Copyright (C) 2012-2017 Edgewall Software