Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expansion of int values sometimes gives strings (when member of object) #19757

Closed
candlerb opened this issue Dec 30, 2016 · 4 comments
Closed
Labels
affects_2.2 This issue/PR affects Ansible v2.2 bug This issue/PR relates to a bug. support:core This issue/PR relates to code supported by the Ansible Engineering Team.

Comments

@candlerb
Copy link
Contributor

ISSUE TYPE
  • Bug Report
COMPONENT NAME

core / vars expansion

ANSIBLE VERSION
ansible 2.2.0.0
  config file =
  configured module search path = Default w/o overrides```
CONFIGURATION

N/A

OS / ENVIRONMENT

Ubuntu 16.04

SUMMARY

A variable assignment can pass through a simple numeric value, but not a numeric value from a member of an object - in that case it gets silently converted to a string.

STEPS TO REPRODUCE
- hosts: localhost

  vars:
    five: 5
    nested:
      five: 5

  tasks:
    - set_fact:
        a: 5
        b: '{{ five }}'
        c: '{{ nested.five }}'

    - debug: msg="a0={{a}}"
    - debug: msg="a1={{a+1}}"
    - debug: msg="b0={{b}}"
    - debug: msg="b1={{b+1}}"
    - debug: msg="c0={{c}}"
    - debug: msg="c1={{c+1}}"
EXPECTED RESULTS

a, b and c are the number 5; the values of a+1, b+1 and c+1 are 6.

ACTUAL RESULTS
PLAY [localhost] ***************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [set_fact] ****************************************************************
ok: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "a0=5"
}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "a1=6"
}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "b0=5"
}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "b1=6"
}

TASK [debug] *******************************************************************
ok: [localhost] => {
    "msg": "c0=5"
}

TASK [debug] *******************************************************************
fatal: [localhost]: FAILED! => {"failed": true, "msg": "Unexpected templating type error occurred on (c1={{c+1}}): coercing to Unicode: need string or buffer, int found"}
	to retry, use: --limit @/home/ubuntu/vtp/ansible/bar.retry

That is, the value of c is a string not a number.

STEPS TO REPRODUCE

Here is another example, this time using the vars option to the template module. The final test case, using with_items, is the actual use case which bit me.

templates/test.j2

{% for i in range(num) %}
{{ i }}
{% endfor %}

foo.yml

- hosts: localhost

  tasks:
    - name: test with direct var
      template:
        src: test.j2
        dest: /tmp/f1
      vars:
        num: 5

    - name: test with item var
      template:
        src: test.j2
        dest: '{{ item.filename }}'
      vars:
        num: '{{ item.count }}'
      with_items:
        - { filename: '/tmp/f2', count: 5 }
EXPECTED RESULTS

In both cases, the template would be expanded with num equal to the number 5.

ACTUAL RESULTS
PLAY [localhost] ***************************************************************

TASK [setup] *******************************************************************
ok: [localhost]

TASK [test with direct var] ****************************************************
ok: [localhost]

TASK [test with item var] ******************************************************
failed: [localhost] (item={u'count': 5, u'filename': u'/tmp/f2'}) => {"failed": true, "item": {"count": 5, "filename": "/tmp/f2"}, "msg": "AnsibleError: Unexpected templating type error occurred on ({% for i in range(num) %}\n{{ i }}\n{% endfor %}\n): an integer is required"}
	to retry, use: --limit @/home/ubuntu/vtp/ansible/foo.retry

That is, in the with_items case, the value is string "5" rather than number 5.

WORKAROUND

Change the template so it says:

{% for i in range(num | int) %}
{{ i }}
{% endfor %}

But this seems very arbitrary. Surely an integer value is always an integer value?

@ansibot ansibot added affects_2.2 This issue/PR affects Ansible v2.2 bug_report needs_triage Needs a first human triage before being processed. labels Dec 30, 2016
@candlerb
Copy link
Contributor Author

Interestingly, the same problem doesn't seem to occur with boolean values.

templates/test.j2

{% if flag %}
flag is True
{% else %}
flag is False
{% endif %}
{% if item.ok %}
item.ok is True
{% else %}
item.ok is False
{% endif %}

foo.yml

- hosts: localhost

  tasks:
    - name: test with item var
      template:
        src: test.j2
        dest: '{{ item.filename }}'
      vars:
        flag: '{{ item.ok }}'
      with_items:
        - { filename: '/tmp/f1', ok: False }
        - { filename: '/tmp/f2', ok: True }

Gives:

$ cat /tmp/f1
flag is False
item.ok is False
$ cat /tmp/f2
flag is True
item.ok is True

@nitzmahone nitzmahone removed the needs_triage Needs a first human triage before being processed. label Jan 5, 2017
@alikins
Copy link
Contributor

alikins commented Jan 5, 2017

This sounds like a dupe of #17992 ?

@ansibot ansibot added the support:core This issue/PR relates to code supported by the Ansible Engineering Team. label Jun 29, 2017
@dagwieers
Copy link
Member

dagwieers commented Sep 21, 2017

There is a light at the end of the tunnel. We made a change to Jinja2 so we don't see all variable types changed into strings. See: pallets/jinja#708

@dagwieers
Copy link
Member

Duplicate of #17992

@dagwieers dagwieers marked this as a duplicate of #17992 Nov 1, 2017
@ansibot ansibot added bug This issue/PR relates to a bug. and removed bug_report labels Mar 7, 2018
@ansible ansible locked and limited conversation to collaborators Apr 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.2 This issue/PR affects Ansible v2.2 bug This issue/PR relates to a bug. support:core This issue/PR relates to code supported by the Ansible Engineering Team.
Projects
None yet
Development

No branches or pull requests

5 participants