Add the accumulate filter (#9133)
* Add the accumulate filter - Add myself as a maintainer for it. - Some integration tests. * accumulate: fix documentation and add test aliases The aliases file was copied over from tests/integrations/targets/filter_dict/aliases as the documentation[1] suggests to use the same group as existing similar tests. [1]: https://docs.ansible.com/ansible/latest/dev_guide/testing/sanity/integration-aliases.html Suggested-by: Felix Fontein <felix@fontein.de> * accumulate: documentation: markup consistency with other plugins Suggested-by: Felix Fontein <felix@fontein.de> Suggested-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> * filter/accumulate: Validate input is a Sequence Accepting arbitrary iterables might lead to surprising behavior so we are stricter on what we accept in the filter. Relaxing those requirements is easier than retrofitting them, in terms of backwards compatibility. Suggested-by: Felix Fontein <felix@fontein.de> Signed-off-by: Max Gautier <mg@max.gautier.name> * filter/accumulate: Document the behavior with a string Signed-off-by: Max Gautier <mg@max.gautier.name> --------- Signed-off-by: Max Gautier <mg@max.gautier.name>pull/9223/head
parent
d826dd1c88
commit
a789bd128f
|
@ -135,6 +135,8 @@ files:
|
||||||
$doc_fragments/xenserver.py:
|
$doc_fragments/xenserver.py:
|
||||||
labels: xenserver
|
labels: xenserver
|
||||||
maintainers: bvitnik
|
maintainers: bvitnik
|
||||||
|
$filters/accumulate.py:
|
||||||
|
maintainers: VannTen
|
||||||
$filters/counter.py:
|
$filters/counter.py:
|
||||||
maintainers: keilr
|
maintainers: keilr
|
||||||
$filters/crc32.py:
|
$filters/crc32.py:
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
# Copyright (c) Max Gautier <mg@max.gautier.name>
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
name: accumulate
|
||||||
|
short_description: Produce a list of accumulated sums of the input list contents
|
||||||
|
version_added: 10.1.0
|
||||||
|
author: Max Gautier (@VannTen)
|
||||||
|
description:
|
||||||
|
- Passthrough to the L(Python itertools.accumulate function,https://docs.python.org/3/library/itertools.html#itertools.accumulate).
|
||||||
|
- Transforms an input list into the cumulative list of results from applying addition to the elements of the input list.
|
||||||
|
- Addition means the default Python implementation of C(+) for input list elements type.
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: A list.
|
||||||
|
type: list
|
||||||
|
elements: any
|
||||||
|
required: true
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = '''
|
||||||
|
_value:
|
||||||
|
description: A list of cumulated sums of the elements of the input list.
|
||||||
|
type: list
|
||||||
|
elements: any
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = '''
|
||||||
|
- name: Enumerate parent directories of some path
|
||||||
|
ansible.builtin.debug:
|
||||||
|
var: >
|
||||||
|
"/some/path/to/my/file"
|
||||||
|
| split('/') | map('split', '/')
|
||||||
|
| community.general.accumulate | map('join', '/')
|
||||||
|
# Produces: ['', '/some', '/some/path', '/some/path/to', '/some/path/to/my', '/some/path/to/my/file']
|
||||||
|
- name: Growing string
|
||||||
|
ansible.builtin.debug:
|
||||||
|
var: "'abc' | community.general.accumulate"
|
||||||
|
# Produces ['a', 'ab', 'abc']
|
||||||
|
'''
|
||||||
|
|
||||||
|
from itertools import accumulate
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
|
from ansible.errors import AnsibleFilterError
|
||||||
|
|
||||||
|
|
||||||
|
def list_accumulate(sequence):
|
||||||
|
if not isinstance(sequence, Sequence):
|
||||||
|
raise AnsibleFilterError('Invalid value type (%s) for accumulate (%r)' %
|
||||||
|
(type(sequence), sequence))
|
||||||
|
|
||||||
|
return accumulate(sequence)
|
||||||
|
|
||||||
|
|
||||||
|
class FilterModule(object):
|
||||||
|
|
||||||
|
def filters(self):
|
||||||
|
return {
|
||||||
|
'accumulate': list_accumulate,
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
azp/posix/3
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
# Copyright (c), Max Gautier <mg@max.gautier.name>
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
- name: Filter | Accumulate | Test valid values
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'abc' | community.general.accumulate == ['a', 'ab', 'abc']"
|
||||||
|
- "['a', 'b'] | community.general.accumulate == ['a', 'ab']"
|
||||||
|
- "[1, 2, 3] | community.general.accumulate == [1, 3, 6]"
|
||||||
|
- "[['foo'],['bar'],['foobar']] | community.general.accumulate == [['foo'], ['foo', 'bar'], ['foo', 'bar', 'foobar']]"
|
||||||
|
- "'path/to/file' | split('/') | map('split', '/') | community.general.accumulate | map('join', '/') == ['path', 'path/to', 'path/to/file']"
|
||||||
|
- "[{'foo':1}, {'bar':2}] | map('dict2items') | community.general.accumulate | map('items2dict') == [{'foo':1}, {'foo':1, 'bar':2}]"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Filter | Accumulate | Test invalid values | Integer
|
||||||
|
debug:
|
||||||
|
var: "1 | community.general.accumulate"
|
||||||
|
register: integer_result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Filter | Accumulate | Test invalid values | Non uniform list
|
||||||
|
debug:
|
||||||
|
var: "['aa', 1] | community.general.accumulate"
|
||||||
|
register: non_uniform_list_result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Filter | Accumulate | Test invalid values | Check errors
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- integer_result is failed
|
||||||
|
- integer_result.msg is match('Invalid value type.*')
|
||||||
|
- non_uniform_list_result is failed
|
||||||
|
- non_uniform_list_result.msg is match('Unexpected templating type error.*can only concatenate str.*')
|
Loading…
Reference in New Issue