From c8acb9a54237b367f514c58e913bb0f5aac14855 Mon Sep 17 00:00:00 2001 From: Ian Wilson Date: Sat, 15 Jun 2024 15:34:18 -0700 Subject: [PATCH] Passing keyword only args as positional should fail. --- mako/ast.py | 8 ++++++++ test/test_def.py | 19 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/mako/ast.py b/mako/ast.py index e59df3e..18cae5b 100644 --- a/mako/ast.py +++ b/mako/ast.py @@ -172,6 +172,14 @@ def get_argument_expressions(self, as_call=False): else: namedecls.append(name) + # A bare `*` immediately followed by `**kwargs` is not valid python. + # Ie. Using a bare `*` without any named keyword arguments. + # A bare `*` and `*args` together is not valid python. + # Ie. Using variable positional arguments already means everything + # following that argument must be keyword only. + if not as_call and kwargnames and not self.varargs: + namedecls.append("*") + # Positional arguments if self.varargs: namedecls.append("*" + argnames.pop(0)) diff --git a/test/test_def.py b/test/test_def.py index fd96433..fd4639c 100644 --- a/test/test_def.py +++ b/test/test_def.py @@ -1,6 +1,6 @@ from mako import lookup from mako.template import Template -from mako.testing.assertions import assert_raises +from mako.testing.assertions import assert_raises, assert_raises_message from mako.testing.assertions import eq_ from mako.testing.fixtures import TemplateTest from mako.testing.helpers import flatten_result @@ -62,6 +62,23 @@ def test_def_py3k_args(self): """look at all these args: one two three four 5 seven""", ) + def test_def_py3k_kwonly_as_pos(self): + """Test that using position arg for kwonly argument fails.""" + template = Template( + """ + <%def name="kwonly(one, *, two)"> + look at all these args: ${one} ${two}""" + """ + + + ${kwonly('one', 'two')}""" + ) + assert_raises_message( + TypeError, + "takes 1 positional argument but 2 were given", + template.render, + ) + def test_inter_def(self): """test defs calling each other""" template = Template(