Search code examples
pythonmako

How do I force a Mako function to require named arguments?


With Python, you can require arguments to be named when a function is called, e.g.

def myfunc (a, b, *, c, d):
   print(f"arguments c and d must be named arguments")

myfunc(1,2,3,4)

>>> TypeError: myfunc() takes 2 positional arguments but 4 were given

That same syntax doesn't seem to work for me when defining a Mako function:

from mako.template import Template
s = """\
<%def name="myfunc (a, b, *, c, d)">
I want to require that arguments c=${c} and d=${d} are named
</%def>
${myfunc(1,2,3,4)}
"""
print(Template(s).render())

>>> I want to require that arguments c=3 and d=4 are named

The * doesn't cause a syntax error, so it appears that Mako is just ignoring it. Am I doing something wrong or is there another way to accomplish the forcing of named arguments?


Solution

  • You cannot force named arguments right now. It seems like a bug in the implementation. Also it looks like positional only arguments probably wouldn't work but I think these were added much later. I'm not sure if this was intended but this feature was added forever ago so now it would probably be hard to "fix".

    For example this test will fail with the current implementation:

        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}"""
                """
            </%def>
    
            ${kwonly('one', 'two')}"""
            )
            assert_raises_message(TypeError, "takes 1 positional argument but 2 were given", template.render)
    

    https://github.com/sqlalchemy/mako/commit/836e5f97e84088cd3104cb3a30bf02e8a6c0a9a5