diff --git a/changelogs/fragments/79083-jinja2_native-preserve-quotes-in-strings.yml b/changelogs/fragments/79083-jinja2_native-preserve-quotes-in-strings.yml new file mode 100644 index 00000000000..f68c80f09f7 --- /dev/null +++ b/changelogs/fragments/79083-jinja2_native-preserve-quotes-in-strings.yml @@ -0,0 +1,2 @@ +bugfixes: + - "jinja2_native: preserve quotes in strings (https://github.com/ansible/ansible/issues/79083)" diff --git a/lib/ansible/template/native_helpers.py b/lib/ansible/template/native_helpers.py index b6fc37b57dc..343e10c709d 100644 --- a/lib/ansible/template/native_helpers.py +++ b/lib/ansible/template/native_helpers.py @@ -128,7 +128,7 @@ def ansible_native_concat(nodes): out = ''.join([to_text(v) for v in nodes]) try: - return ast.literal_eval( + evaled = 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. @@ -136,3 +136,9 @@ def ansible_native_concat(nodes): ) except (ValueError, SyntaxError, MemoryError): return out + + if isinstance(evaled, string_types): + quote = out[0] + return f'{quote}{evaled}{quote}' + + return evaled diff --git a/test/integration/targets/jinja2_native_types/runme.sh b/test/integration/targets/jinja2_native_types/runme.sh index f648f875021..a6c2befa151 100755 --- a/test/integration/targets/jinja2_native_types/runme.sh +++ b/test/integration/targets/jinja2_native_types/runme.sh @@ -7,4 +7,5 @@ ansible-playbook runtests.yml -v "$@" ansible-playbook --vault-password-file test_vault_pass test_vault.yml -v "$@" ansible-playbook test_hostvars.yml -v "$@" ansible-playbook nested_undefined.yml -v "$@" +ansible-playbook test_preserving_quotes.yml -v "$@" unset ANSIBLE_JINJA2_NATIVE diff --git a/test/integration/targets/jinja2_native_types/test_casting.yml b/test/integration/targets/jinja2_native_types/test_casting.yml index 8627a0563c9..5e9c76d628c 100644 --- a/test/integration/targets/jinja2_native_types/test_casting.yml +++ b/test/integration/targets/jinja2_native_types/test_casting.yml @@ -13,7 +13,7 @@ - assert: that: - - 'int_to_str == "2"' + - int_to_str == "'2'" - 'int_to_str|type_debug in ["str", "unicode"]' - 'int_to_str2 == "2"' - 'int_to_str2|type_debug in ["NativeJinjaText"]' diff --git a/test/integration/targets/jinja2_native_types/test_concatentation.yml b/test/integration/targets/jinja2_native_types/test_concatentation.yml index 8a8077b6699..24a90381e12 100644 --- a/test/integration/targets/jinja2_native_types/test_concatentation.yml +++ b/test/integration/targets/jinja2_native_types/test_concatentation.yml @@ -22,7 +22,7 @@ - assert: that: - - 'string_sum == "12"' + - string_sum == "'12'" - 'string_sum|type_debug in ["str", "unicode"]' - name: add two lists diff --git a/test/integration/targets/jinja2_native_types/test_preserving_quotes.yml b/test/integration/targets/jinja2_native_types/test_preserving_quotes.yml new file mode 100644 index 00000000000..d6fea10ea6c --- /dev/null +++ b/test/integration/targets/jinja2_native_types/test_preserving_quotes.yml @@ -0,0 +1,14 @@ +- hosts: localhost + gather_facts: false + tasks: + - assert: + that: + - quoted_str == '"hello"' + - empty_quoted_str == '""' + vars: + third_nested_lvl: '"hello"' + second_nested_lvl: "{{ third_nested_lvl }}" + first_nested_lvl: "{{ second_nested_lvl }}" + quoted_str: "{{ first_nested_lvl }}" + empty_quoted_str: "{{ empty_str }}" + empty_str: '""'