From 95e120ed02d108ecf085ba14f0ade2209e94d894 Mon Sep 17 00:00:00 2001 From: Martin Krizek Date: Thu, 11 Nov 2021 20:12:46 +0100 Subject: [PATCH] Keep pre Python 3.10 literal_eval behavior (#76261) --- changelogs/fragments/jinja2_native-literal_eval-py310.yml | 2 ++ lib/ansible/playbook/conditional.py | 7 +------ lib/ansible/template/native_helpers.py | 7 ++++++- 3 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 changelogs/fragments/jinja2_native-literal_eval-py310.yml diff --git a/changelogs/fragments/jinja2_native-literal_eval-py310.yml b/changelogs/fragments/jinja2_native-literal_eval-py310.yml new file mode 100644 index 00000000000..70a66af8e8c --- /dev/null +++ b/changelogs/fragments/jinja2_native-literal_eval-py310.yml @@ -0,0 +1,2 @@ +minor_changes: + - jinja2_native - keep same behavior on Python 3.10. diff --git a/lib/ansible/playbook/conditional.py b/lib/ansible/playbook/conditional.py index f3118a81b29..5a909e7c9ee 100644 --- a/lib/ansible/playbook/conditional.py +++ b/lib/ansible/playbook/conditional.py @@ -184,12 +184,7 @@ class Conditional: # NOTE The spaces around True and False are intentional to short-circuit literal_eval for # jinja2_native=False and avoid its expensive calls. presented = "{%% if %s %%} True {%% else %%} False {%% endif %%}" % conditional - # NOTE Convert the result to text to account for both native and non-native jinja. - # NOTE The templated result of `presented` is string on native jinja as well prior to Python 3.10. - # ast.literal_eval on Python 3.10 removes leading whitespaces so " True " becomes bool True - # as opposed to Python 3.9 and lower where the same would result in IndentationError and - # string " True " would be returned by Templar. - val = to_text(templar.template(presented, disable_lookups=disable_lookups)).strip() + val = templar.template(presented, disable_lookups=disable_lookups).strip() if val == "True": return True elif val == "False": diff --git a/lib/ansible/template/native_helpers.py b/lib/ansible/template/native_helpers.py index 63d6bdc6712..c75d356b38a 100644 --- a/lib/ansible/template/native_helpers.py +++ b/lib/ansible/template/native_helpers.py @@ -140,6 +140,11 @@ def ansible_native_concat(nodes): out = ''.join([to_text(_fail_on_undefined(v)) for v in chain(head, nodes)]) try: - return ast.literal_eval(out) + return ast.literal_eval( + # In Python 3.10+ ast.literal_eval removes leading spaces/tabs + # from the given string. For backwards compatibility we need to + # parse the string ourselves without removing leading spaces/tabs. + ast.parse(out, mode='eval') + ) except (ValueError, SyntaxError, MemoryError): return out