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

Allow loop on dict keys like python #53041

Closed
guoqiao opened this issue Feb 27, 2019 · 8 comments
Closed

Allow loop on dict keys like python #53041

guoqiao opened this issue Feb 27, 2019 · 8 comments
Labels
affects_2.8 This issue/PR affects Ansible v2.8 feature This issue/PR relates to a feature request. support:core This issue/PR relates to code supported by the Ansible Engineering Team.

Comments

@guoqiao
Copy link
Contributor

guoqiao commented Feb 27, 2019

SUMMARY

Allow loop on dict keys like python.

ISSUE TYPE
  • Feature Idea
COMPONENT NAME
  • task_executor
  • loop
ADDITIONAL INFORMATION

Currently ansible support dict loop with dict2items filter:

- name: dict loop example
  debug:
    msg: "my key is {{item.key}}, my value is {{item.value}}"
  loop: '{{my_dict|dict2items}}'

To loop dict, users need to remember a few things in mind:

  • filter dict2items
  • use item to refer to item
  • use item.key to refer to key
  • use item.value to refer to value

Considering dict is so common everywhere, above syntax is actually too trivial and overloaded.
The python equavelant is:

for item in [{'key': key, 'value': value} for key, value in my_dict.items()]:
    print(item)

In python, you can also loop dict just like list:

for key in my_dict:
    val = my_dict[key]
    print(val)

this is handy for usage, breif and consistent in syntax.
Any one with basic python expericence will expect to use similar syntax in ansible:

- name: loop dict on key
  debug:
    msg: "dict value for {{item}} is {{my_dict[item]}}"
  loop: '{{my_dict}}'

But ansible loop forbid that, which is a pity and unnecessary.
This patch enables this feature with tiny change.

Example and compare:

- hosts: localhost
  vars:
    my_list:
      - item0
      - item1
    my_dict:
      key0: val0
      key1: val1
  tasks:

    - name: loop on list
      debug: var=item
      loop: '{{my_list}}'

    - name: loop dict on key
      debug:
        msg: "dict value for {{item}} is {{my_dict[item]}}"
      loop: '{{my_dict}}'

    - name: loop dict with dict2items
      debug:
        msg: "dict value for {{item.key}} is {{item.value}}"
      loop: '{{my_dict|dict2items}}'
@ansibot
Copy link
Contributor

ansibot commented Feb 27, 2019

Files identified in the description:
None

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot added affects_2.8 This issue/PR affects Ansible v2.8 feature This issue/PR relates to a feature request. needs_triage Needs a first human triage before being processed. support:core This issue/PR relates to code supported by the Ansible Engineering Team. labels Feb 27, 2019
@guoqiao
Copy link
Contributor Author

guoqiao commented Feb 27, 2019

I've created a PR #53042 for this.

@ansibot
Copy link
Contributor

ansibot commented Feb 27, 2019

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@bcoca
Copy link
Member

bcoca commented Feb 27, 2019

We prefer to keep the types accepted strict, you can already do what you want this way:

    - name: loop dict on key
      debug:
        msg: "dict value for {{item}} is {{my_dict[item]}}"
      loop: '{{my_dict|list}}'
      vars:
        my_dict:
            a: 1
            b: 2

@guoqiao
Copy link
Contributor Author

guoqiao commented Feb 27, 2019

@bcoca nice, this is already much better than dict2items.
However, I am still not comfortable with the fact that loop only works on list, it should work on any iterable/loopable like python.
To be strict on types is good, but for the loop case, it should mean items must be iterable other than items must be list.

@bcoca
Copy link
Member

bcoca commented Feb 27, 2019

Most non programmers understand 'a list' but not 'iterable', a string is also 'iterable' but we don't want to:

- debug: var=item
 loop: thisisastring

to output

t
h
i
s
....

@bcoca bcoca removed the needs_triage Needs a first human triage before being processed. label Mar 5, 2019
@sivel
Copy link
Member

sivel commented Mar 5, 2019

We have discussed this and decided that loop should not be expanded this way. We have plans to address loop UX, and are exploring several proposals. Please see the following links for more information.

ansible/proposals#99
ansible/proposals#140

If you have further questions please stop by IRC or the mailing list:

@sivel sivel closed this as completed Mar 5, 2019
@guoqiao
Copy link
Contributor Author

guoqiao commented Mar 5, 2019

@sivel thanks.

@ansible ansible locked and limited conversation to collaborators Jul 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.8 This issue/PR affects Ansible v2.8 feature This issue/PR relates to a feature request. support:core This issue/PR relates to code supported by the Ansible Engineering Team.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants