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