From 82ad8ff08173265ed5e27181022b37192730b37c Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Mon, 10 Apr 2017 11:22:06 -0700 Subject: [PATCH] Add documentation of Jinja2 templating idioms that differ when run under Python3 Fixes #19514 --- docs/docsite/rst/playbooks_python_version.rst | 69 +++++++++++++++++++ docs/docsite/rst/playbooks_templating.rst | 2 +- docs/docsite/rst/playbooks_variables.rst | 5 ++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 docs/docsite/rst/playbooks_python_version.rst diff --git a/docs/docsite/rst/playbooks_python_version.rst b/docs/docsite/rst/playbooks_python_version.rst new file mode 100644 index 00000000000..519fff3f370 --- /dev/null +++ b/docs/docsite/rst/playbooks_python_version.rst @@ -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 ` 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 ` 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 ` is necessary + here. diff --git a/docs/docsite/rst/playbooks_templating.rst b/docs/docsite/rst/playbooks_templating.rst index bae594f71fc..62a6f04ea08 100644 --- a/docs/docsite/rst/playbooks_templating.rst +++ b/docs/docsite/rst/playbooks_templating.rst @@ -14,7 +14,7 @@ Please note that all templating happens on the Ansible controller before the tas playbooks_filters playbooks_tests playbooks_lookups - + playbooks_python_version .. seealso:: diff --git a/docs/docsite/rst/playbooks_variables.rst b/docs/docsite/rst/playbooks_variables.rst index 1921fe3d7b0..68282f6d0c5 100644 --- a/docs/docsite/rst/playbooks_variables.rst +++ b/docs/docsite/rst/playbooks_variables.rst @@ -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 possibilities. +.. seealso:: + + :doc:`playbooks_templating` + More information about Jinja2 templating + .. _jinja2_filters: Jinja2 Filters