59e4879
Patch from Tim Hatch
59e4879
http://genshi.edgewall.org/ticket/602
59e4879
59e4879
diff --git a/genshi/filters/i18n.py b/genshi/filters/i18n.py
59e4879
index b724956..dfb52b8 100644
59e4879
--- a/genshi/filters/i18n.py
59e4879
+++ b/genshi/filters/i18n.py
59e4879
@@ -1187,8 +1187,10 @@ def extract_from_code(code, gettext_functions):
59e4879
                 elif arg:
59e4879
                     strings.append(None)
59e4879
             [_add(arg) for arg in node.args]
59e4879
-            _add(node.starargs)
59e4879
-            _add(node.kwargs)
59e4879
+            if hasattr(node, 'starargs'):
59e4879
+                _add(node.starargs)
59e4879
+            if hasattr(node, 'kwargs'):
59e4879
+                _add(node.kwargs)
59e4879
             if len(strings) == 1:
59e4879
                 strings = strings[0]
59e4879
             else:
59e4879
diff --git a/genshi/template/astutil.py b/genshi/template/astutil.py
59e4879
index a3946b4..07edc92 100644
59e4879
--- a/genshi/template/astutil.py
59e4879
+++ b/genshi/template/astutil.py
59e4879
@@ -148,6 +148,10 @@ class ASTCodeGenerator(object):
59e4879
         def visit_arg(self, node):
59e4879
             self._write(node.arg)
59e4879
 
59e4879
+    def visit_Starred(self, node):
59e4879
+        self._write('*')
59e4879
+        self.visit(node.value)
59e4879
+
59e4879
     # FunctionDef(identifier name, arguments args,
59e4879
     #                           stmt* body, expr* decorator_list)
59e4879
     def visit_FunctionDef(self, node):
59e4879
@@ -661,9 +665,13 @@ class ASTCodeGenerator(object):
59e4879
             if not first:
59e4879
                 self._write(', ')
59e4879
             first = False
59e4879
-            # keyword = (identifier arg, expr value)
59e4879
-            self._write(keyword.arg)
59e4879
-            self._write('=')
59e4879
+            if not keyword.arg:
59e4879
+                # Python 3.5+ star-star args
59e4879
+                self._write('**')
59e4879
+            else:
59e4879
+                # keyword = (identifier arg, expr value)
59e4879
+                self._write(keyword.arg)
59e4879
+                self._write('=')
59e4879
             self.visit(keyword.value)
59e4879
         if getattr(node, 'starargs', None):
59e4879
             if not first:
59e4879
diff --git a/genshi/template/directives.py b/genshi/template/directives.py
59e4879
index 7301c2d..6fd0f28 100644
59e4879
--- a/genshi/template/directives.py
59e4879
+++ b/genshi/template/directives.py
59e4879
@@ -266,13 +266,21 @@ class DefDirective(Directive):
59e4879
         if isinstance(ast, _ast.Call):
59e4879
             self.name = ast.func.id
59e4879
             for arg in ast.args:
59e4879
-                # only names
59e4879
-                self.args.append(arg.id)
59e4879
+                if isinstance(arg, _ast.Starred):
59e4879
+                    # Python 3.5+
59e4879
+                    self.star_args = arg.value.id
59e4879
+                else:
59e4879
+                    # only names
59e4879
+                    self.args.append(arg.id)
59e4879
             for kwd in ast.keywords:
59e4879
-                self.args.append(kwd.arg)
59e4879
-                exp = Expression(kwd.value, template.filepath,
59e4879
-                                 lineno, lookup=template.lookup)
59e4879
-                self.defaults[kwd.arg] = exp
59e4879
+                if kwd.arg is None:
59e4879
+                    # Python 3.5+
59e4879
+                    self.dstar_args = kwd.value.id
59e4879
+                else:
59e4879
+                    self.args.append(kwd.arg)
59e4879
+                    exp = Expression(kwd.value, template.filepath,
59e4879
+                                     lineno, lookup=template.lookup)
59e4879
+                    self.defaults[kwd.arg] = exp
59e4879
             if getattr(ast, 'starargs', None):
59e4879
                 self.star_args = ast.starargs.id
59e4879
             if getattr(ast, 'kwargs', None):
59e4879
diff --git a/genshi/template/eval.py b/genshi/template/eval.py
59e4879
index de4bc86..065c0c7 100644
59e4879
--- a/genshi/template/eval.py
59e4879
+++ b/genshi/template/eval.py
59e4879
@@ -597,6 +597,11 @@ class TemplateASTTransformer(ASTTransformer):
59e4879
         finally:
59e4879
             self.locals.pop()
59e4879
 
59e4879
+    # Only used in Python 3.5+
59e4879
+    def visit_Starred(self, node):
59e4879
+        node.value = self.visit(node.value)
59e4879
+        return node
59e4879
+
59e4879
     def visit_Name(self, node):
59e4879
         # If the name refers to a local inside a lambda, list comprehension, or
59e4879
         # generator expression, leave it alone