Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jinja2 - copy variable instead of referencing it

Tags:

python

jinja2

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?

like image 297
Elias Probst Avatar asked Oct 27 '25 23:10

Elias Probst


2 Answers

$ 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())
like image 149
Unapiedra Avatar answered Oct 30 '25 13:10

Unapiedra


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

like image 42
gusmb Avatar answered Oct 30 '25 14:10

gusmb