Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions docs/docsite/rst/porting_guides/porting_guide_core_2.19.rst
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,41 @@ The result of the corrected template remains a list:
}


Example - unintentional ``None`` result
"""""""""""""""""""""""""""""""""""""""

If a template evaluated to ``None``, it was implicitly converted to an empty string in previous versions of ansible-core.
This can now result in the template evaluating to the *value* ``None``.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth pointing out that this no longer matters for the common case of passing the template result to a module argument that accepts a string, since None is now automatically converted to an empty string in that case.

See: ansible/ansible#85652

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I didn't notice that change. That doesn't work for type=list though, where an empty string as a result of a template in 2.18 and before resulted in [""], and now results in an error. But since [""] was seldom the expected value I guess this doesn't matter much...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a note: dbe43f4
Does this look good?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks better.

Your point about lists has me wondering if they should default to [] when given None for module arguments, since that's the closest thing to "no list" -- just like we now do for strings defaulting to "" when None is given.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defaulting to [] would be changing behavior (since depending on where None comes from, it used to be [""] before). That sounds like a can of worm that can cause more bad than good. At least for strings, None either came from a template (and used to be "") or was invalid before.


The following example shows a case where this happens:

.. code-block:: yaml+jinja

- set_fact:
# If 'foo' is not defined, the else branch basically evaluates to None.
# So value_none will not be an empty string, but None:
value_none: |-
{% if foo is defined %}foo is defined{% endif %}

This example can be fixed as follows:

.. code-block:: yaml+jinja

- set_fact:
# Explicitly return an empty string in the 'else' branch.
# The value is always a string: either "foo is defined" or "".
value_none: |-
{% if foo is defined %}foo is defined{% else %}{{ "" }}{% endif %}

This adjustment is backward-compatible with older ansible-core versions.

.. note::
Since ansible-core 2.19.1, module options of type string accept ``None`` and convert it
to an empty string. Before ansible-core 2.18, passing ``None`` to such options resulted
in an error. This means that in most cases, expressions in roles and playbooks do not need
to be adjusted because of unintentional ``None`` results.


Lazy templating
^^^^^^^^^^^^^^^

Expand Down