jinja icon indicating copy to clipboard operation
jinja copied to clipboard

Sandbox format_map in for loop: TypeError: format_map() takes exactly one argument 2 given

Open lufik opened this issue 4 months ago • 0 comments

We start receiving jinja2 error with sandbox and format_map function inside for loop after upgrade jinja2 2.10 to jinja2 3.1.3:

              Unable to manage file: Jinja error: format_map() takes exactly one argument 2 given
              Traceback (most recent call last):
                File "/opt/salt/lib/python3.10/site-packages/salt/utils/templates.py", line 468, in render_jinja_tmpl
                  output = template.render(**decoded_context)
                File "/opt/salt/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
                  self.environment.handle_exception()
                File "/opt/salt/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
                  raise rewrite_traceback_stack(source=source)
                File "<template>", line 274, in top-level template code
                File "/opt/salt/lib/python3.10/site-packages/jinja2/sandbox.py", line 387, in call
                  return __self.format_string(fmt, args, kwargs, __obj)
                File "/opt/salt/lib/python3.10/site-packages/jinja2/sandbox.py", line 366, in format_string
                  raise TypeError(
              TypeError: format_map() takes exactly one argument 2 given
              
              ; line 274

I can reproduce it with this code:

import jinja2
import jinja2.sandbox
import os

TEMPLATE_FILE = './test.j2'
OUT_FILE = './test.txt'

def main():
    loader = jinja2.FileSystemLoader(os.path.dirname('.'))
    jinja_env = jinja2.sandbox.SandboxedEnvironment()

    # Open the template
    with open(TEMPLATE_FILE, 'r') as template_file:
        template = jinja_env.from_string(template_file.read())

    # Assign the finished string to 'output'
    output = template.render()

    with open(OUT_FILE, 'w') as outfile:
        outfile.write(output)

if __name__ == '__main__':
    main()

and template test.j2:

{% set fmt_map = {
     "a" : "atext"
   } %}
{{ "test".format_map(fmt_map) }}
{% for i in range(1,2) %}
  {{ "test".format_map(fmt_map) }}
{% endfor %}

It seems newer version adds _loop_vars into kwargs and sandboxed format_map do not count with it.

Environment:

  • Python version: 3.10.14
  • Jinja version: 3.1.3

lufik avatar Oct 08 '24 17:10 lufik