ansible/docs/docsite/rst/user_guide/playbooks_python_version.rst
scottb 373b1dcf59
Core Docs Refactor and Redesign (#36067)
* Docs refactor as outlined in https://github.com/ansible/proposals/issues/79. Moves content into 'guides'; refactors TOC; fixes CSS; design tweaks to layout and CSS; fixes generated plugin, CLI and module docs to fix links accodingly; more.

* Adding extra blank line for shippable
2018-02-13 07:23:55 -08:00

2.4 KiB

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.

Dictionary Views

In Python2, the dict.keys, dict.values, and 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 return a dictionary view <python3:dict-views> object. The string representation that Jinja2 returns for dictionary views cannot be parsed back into a list by Ansible. It is, however, easy to make this portable by using the list <jinja2:list> filter whenever using dict.keys, dict.values, or dict.items:

vars:
  hosts:
    testhost1: 127.0.0.2
    testhost2: 127.0.0.3
tasks:
  - debug:
      msg: '{{ item }}'
    # Only works with Python 2
    #loop: "{{ hosts.keys() }}"
    # Works with both Python 2 and Python 3
    loop: "{{ hosts.keys() | list }}"

dict.iteritems()

In Python2, dictionaries have ~dict.iterkeys, ~dict.itervalues, and ~dict.iteritems methods. These methods have been removed in Python3. Playbooks and Jinja2 templates should use dict.keys, dict.values, and 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
    #loop: "{{ hosts.iteritems() }}"
    # Works with both Python 2 and Python 3
    loop: "{{ hosts.items() | list }}"

* The pb-py-compat-dict-views entry for information on why the list filter <jinja2:list> is necessary here.