I'd like to be able to copy a variable in Jinja2 (2.10) instead of just referencing it, but couldn't find a way to do it.
See the following example:
from jinja2 import Environment
from jinja2.ext import do
env = Environment(extensions=[do])
template = env.from_string('''
  {%- set base = {"elems": {"a": "aa"}} -%}
  {%- set data = {"elems": base.elems} -%}
  {%- do data.elems.update({"a": "bb"}) -%}
  {{ base.elems.a }} - "aa" expected
  {{ data.elems.a }} - "bb" expected
''')
template.render()
The result is: 'bb - "aa" expected\nbb - "bb" expected'
So this means that data.elems is not a copy of base.elems, but a reference to it instead.
I need to have a copy of base.elems in data.elems instead.
I tried:
base.get('elems')base|attr('elems')But none of those worked. Is there any way to copy values in Jinja2?
$ python q54718238.py
aa - "aa" expected
  bb - "bb" expected
The trick is knowing that a lot of Python's data types are by reference. So, calling copy() on the object fixes it. Note that I changed {%- set data = {"elems": base.elems} -%} to {%- set data = {"elems": base.elems.copy()} -%}.
from jinja2 import Environment
from jinja2.ext import do
env = Environment(extensions=[do])
template = env.from_string('''
  {%- set base = {"elems": {"a": "aa"}} -%}
  {%- set data = {"elems": base.elems.copy()} -%}
  {%- do data.elems.update({"a": "bb"}) -%}
  {{ base.elems.a }} - "aa" expected
  {{ data.elems.a }} - "bb" expected
''')
print(template.render())
This didn't work for me when I tried to copy the whole dictionary. I ended up getting the copy by doing the following:
{% set newdict = olddict | to_json | from_json %}
Note: in my case I am using Jinja2 with Ansible and not python directly
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With