From 4416544a24f2af518b9cc431766465d19283b618 Mon Sep 17 00:00:00 2001 From: Martin Krizek Date: Thu, 2 Dec 2021 13:40:03 +0100 Subject: [PATCH 1/2] Clarify unroll in _finalize Clarifies that unrolling in _finalize is actually necessary. Also using decorator directly. --- lib/ansible/template/__init__.py | 33 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/lib/ansible/template/__init__.py b/lib/ansible/template/__init__.py index 69bedf6c5fc375..72d19d5fbc44be 100644 --- a/lib/ansible/template/__init__.py +++ b/lib/ansible/template/__init__.py @@ -261,7 +261,7 @@ def _is_rolled(value): def _unroll_iterator(func): - """Wrapper function, that intercepts the result of a filter + """Wrapper function, that intercepts the result of a templating and auto unrolls a generator, so that users are not required to explicitly use ``|list`` to unroll. """ @@ -916,22 +916,23 @@ def _convert_bare_variable(self, variable): # so just return it as-is return variable + @_unroll_iterator def _finalize(self, thing): - ''' - A custom finalize method for jinja2, which prevents None from being returned. This - avoids a string of ``"None"`` as ``None`` has no importance in YAML. - - If using ANSIBLE_JINJA2_NATIVE we bypass this and return the actual value always - ''' - if _is_rolled(thing): - # Auto unroll a generator, so that users are not required to - # explicitly use ``|list`` to unroll - # This only affects the scenario where the final result of templating - # is a generator, and not where a filter creates a generator in the middle - # of a template. See ``_unroll_iterator`` for the other case. This is probably - # unncessary - return list(thing) - + """A custom finalize method for jinja2, which prevents None from being + returned. This avoids a string of ``"None"`` as ``None`` has no + importance in YAML. + + The method is decorated with ``_unroll_iterator`` so that users are not + required to explicitly use ``|list`` to unroll a generator. This only + affects the scenario where the final result of templating + is a generator, e.g. ``range``, ``dict.items()`` and so on. Filters + which can produce a generator in the middle of a template are already + wrapped with ``_unroll_generator`` in ``JinjaPluginIntercept``. + + If using jinja2_native we bypass this and return the actual value always. + """ + # FIXME remove this special case for jinja2_native by creating separate + # _finalized methods in AnsibleEnvironment/AnsibleNativeEnvironment. if self.jinja2_native: return thing From a475b0c974118582568f2e6da00ef5d518acddaa Mon Sep 17 00:00:00 2001 From: Martin Krizek Date: Thu, 9 Dec 2021 17:40:46 +0100 Subject: [PATCH 2/2] Add changelog --- changelogs/fragments/clarify-unroll.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelogs/fragments/clarify-unroll.yml diff --git a/changelogs/fragments/clarify-unroll.yml b/changelogs/fragments/clarify-unroll.yml new file mode 100644 index 00000000000000..d312165a33ec51 --- /dev/null +++ b/changelogs/fragments/clarify-unroll.yml @@ -0,0 +1,2 @@ +minor_changes: + - Clarify in a comment that unrolling an iterator in ``Templar._finalize`` is actually necessary. Also switch to using the ``_unroll_iterator`` decorator directly to deduplicate code in ``Templar._finalize``. (https://github.com/ansible/ansible/pull/76436)