Add documentation of Jinja2 templating idioms that differ when run under Python3

Fixes #19514
This commit is contained in:
Toshio Kuratomi 2017-04-10 11:22:06 -07:00
parent 4c7a2e2622
commit 82ad8ff081
3 changed files with 75 additions and 1 deletions

View file

@ -0,0 +1,69 @@
.. _pb-py-compat:
Python Version and Templating
=============================
Jinja2 templates leverage Python data types and standard functions. This
makes for a rich set of operations that can be performed on data. However,
this also means that certain specifics of the underlying Python becomes
visible to template authors. Since Ansible playbooks use Jinja2 for templates
and variables, this means that playbook authors need to be aware of these
specifics as well.
Unless otherwise noted, these differences are only of interest when running
Ansible in Python2 versus Python3. Changes within Python2 and Python3 are
generally small enough that they are not visible at the jinja2 level.
.. _pb-py-compat-dict-views:
Dictionary Views
----------------
In Python2, the :meth:`dict.keys`, :meth:`dict.values`, and :meth:`dict.items`
methods returns a list. Jinja2 returns that to Ansible via a string
representation that Ansible can turn back into a list. In Python3, those
methods returns a :ref:`dictionary view <python3:dict-views>` object. The
string representation that Jinja2 returns for dictionary views is not parsable
by Ansible back into a list. It is, however, easy to make this portable by
using the :func:`list <jinja2:list>` filter whenever using :meth:`dict.keys`,
:meth:`dict.values`, or :meth:`dict.items`::
vars:
hosts:
testhost1: 127.0.0.2
testhost2: 127.0.0.3
tasks:
- debug:
msg: '{{ item }}'
# Only works with Python 2
#with_items: "{{ hosts.keys() }}"
# Works with both Python 2 and Python 3
with_items: "{{ hosts.keys() | list }}"
.. _pb-py-compat-iteritems:
dict.iteritems()
----------------
In Python2, dictionaries have :meth:`~dict.iterkeys`,
:meth:`~dict.itervalues`, and :meth:`~dict.iteritems` methods. These methods
have been removed in Python3. Playbooks and Jinja2 templates should use
:meth:`dict.keys`, :meth:`dict.values`, and :meth:`dict.items` in order to be
compatible with both Python2 and Python3::
vars:
hosts:
testhost1: 127.0.0.2
testhost2: 127.0.0.3
tasks:
- debug:
msg: '{{ item }}'
# Only works with Python 2
#with_items: "{{ hosts.iteritems() }}"
# Works with both Python 2 and Python 3
with_items: "{{ hosts.items() | list }}"
.. seealso::
* The :ref:`pb-py-compat-dict-views` entry for information on
why the :func:`list filter <jinja2:list>` is necessary
here.

View file

@ -14,7 +14,7 @@ Please note that all templating happens on the Ansible controller before the tas
playbooks_filters playbooks_filters
playbooks_tests playbooks_tests
playbooks_lookups playbooks_lookups
playbooks_python_version
.. seealso:: .. seealso::

View file

@ -124,6 +124,11 @@ it's more than that -- you can also read variables about other hosts. We'll sho
pieces of files, or to have other ecosystem tools read Ansible files. Not everyone will need this but it can unlock pieces of files, or to have other ecosystem tools read Ansible files. Not everyone will need this but it can unlock
possibilities. possibilities.
.. seealso::
:doc:`playbooks_templating`
More information about Jinja2 templating
.. _jinja2_filters: .. _jinja2_filters:
Jinja2 Filters Jinja2 Filters