mako icon indicating copy to clipboard operation
mako copied to clipboard

strict_undefined flag is incompatible with comprehensions inside functions

Open ks07 opened this issue 5 years ago • 1 comments

Using a list comprehension inside of a pure python function within a template will produce a NameError if the variable name introduced in the comprehension hasn't previously been defined, and strict_undefined=True is provided.

See the following contrived example:

from mako.template import Template

text = """
<%
    mydict = { 'foo': 1 }

    ## Uncomment the following line to workaround the error
    ##k = None
    def getkeys(x):
        return [ k for k in x.keys() ]
%>

${ ','.join( getkeys(mydict) ) }
"""

tmpl = Template(text=text, strict_undefined=True)
out = tmpl.render()
print(out)

The following error is produced:

Traceback (most recent call last):
  File "memory:0x7fe265f30cc0", line 20, in render_body
  File "/home/george/.local/share/virtualenvs/mako_test-_JNqmfEZ/lib/python3.6/site-packages/mako/runtime.py", line 106, in __getitem__
    return compat_builtins.__dict__[key]
KeyError: 'k'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 17, in <module>
    out = tmpl.render()
  File "/home/george/.local/share/virtualenvs/mako_test-_JNqmfEZ/lib/python3.6/site-packages/mako/template.py", line 476, in render
    return runtime._render(self, self.callable_, args, data)
  File "/home/george/.local/share/virtualenvs/mako_test-_JNqmfEZ/lib/python3.6/site-packages/mako/runtime.py", line 883, in _render
    **_kwargs_for_callable(callable_, data)
  File "/home/george/.local/share/virtualenvs/mako_test-_JNqmfEZ/lib/python3.6/site-packages/mako/runtime.py", line 920, in _render_context
    _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)
  File "/home/george/.local/share/virtualenvs/mako_test-_JNqmfEZ/lib/python3.6/site-packages/mako/runtime.py", line 947, in _exec_template
    callable_(context, *args, **kwargs)
  File "memory:0x7fe265f30cc0", line 22, in render_body
NameError: 'k' is not defined

The above code sample works as expected if strict_undefined is set to false.

I am running Python 3.6.9 and Mako 1.1.3

ks07 avatar Jun 19 '20 17:06 ks07

this has to do with Mako's scoping rules. I haven't worked on non-trivial bugs in Mako for many years and Mako is essentially unmaintained for issues like these at the moment. If you had insight on working on this issue I can accept PRs if they also include tests.

zzzeek avatar Jun 19 '20 19:06 zzzeek