1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-03-21 20:59:10 +00:00

adds parameter delimiters to from_ini filter (#11512)

* adds parameter delimiters to from_ini filter

fixes issue #11506

* adds changelog fragment

* fixes pylint dangerous-default-value / W0102

* does not assume default delimiters

let that be decided in the super class

* Update plugins/filter/from_ini.py

verbose description

Co-authored-by: Felix Fontein <felix@fontein.de>

* Update changelogs/fragments/11512-from_ini-delimiters.yaml

Co-authored-by: Felix Fontein <felix@fontein.de>

* adds input validation

* adss check for delimiters not None

* adds missing import

* removes the negation

* adds suggestions from russoz

* adds ruff format suggestion

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
Robert Sander 2026-02-23 05:44:32 +01:00 committed by GitHub
parent ce7cb4e914
commit aec0e61ba1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 52 additions and 4 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- from_ini filter plugin - add ``delimiters`` parameter to allow correctly parsing more INI documents (https://github.com/ansible-collections/community.general/issues/11506, https://github.com/ansible-collections/community.general/pull/11512).

View file

@ -16,6 +16,14 @@ options:
description: A string containing an INI document.
type: string
required: true
delimiters:
description: A list of characters used as delimiters in the INI document.
type: list
elements: string
default:
- "="
- ":"
version_added: 12.4.0
seealso:
- plugin: community.general.to_ini
plugin_type: filter
@ -53,13 +61,17 @@ from configparser import ConfigParser
from io import StringIO
from ansible.errors import AnsibleFilterError
from ansible.module_utils.common.collections import is_sequence
class IniParser(ConfigParser):
"""Implements a configparser which is able to return a dict"""
def __init__(self):
def __init__(self, delimiters=None):
if delimiters is None:
super().__init__(interpolation=None)
else:
super().__init__(interpolation=None, delimiters=delimiters)
self.optionxform = str
def as_dict(self):
@ -74,13 +86,21 @@ class IniParser(ConfigParser):
return d
def from_ini(obj):
def from_ini(obj, delimiters=None):
"""Read the given string as INI file and return a dict"""
if not isinstance(obj, str):
raise AnsibleFilterError(f"from_ini requires a str, got {type(obj)}")
if delimiters is not None:
if not is_sequence(delimiters):
raise AnsibleFilterError(f"from_ini's delimiters parameter must be a sequence, got {type(delimiters)}")
delimiters = tuple(delimiters)
if not all(isinstance(elt, str) for elt in delimiters):
raise AnsibleFilterError(
f"from_ini's delimiters parameter must be a sequence of strings, got {delimiters!r}"
)
parser = IniParser()
parser = IniParser(delimiters=delimiters)
try:
parser.read_file(StringIO(obj))

View file

@ -41,6 +41,32 @@
- 'ini_file_content.content | b64decode | community.general.from_ini ==
ini_test_dict'
- name: 'Define another ini_test_dict'
ansible.builtin.set_fact:
ini_test_dict:
section_name:
'key_name * : with spaces': 'key value'
- name: 'Write another INI file that reflects ini_test_dict to {{ ini_test_file }}'
ansible.builtin.copy:
dest: '{{ ini_test_file }}'
content: |
[section_name]
key_name * : with spaces = key value
- name: 'Slurp the other test file: {{ ini_test_file }}'
ansible.builtin.slurp:
src: '{{ ini_test_file }}'
register: 'ini_file_content'
- name: >-
Ensure defined ini_test_dict is the same when retrieved
from other {{ ini_test_file }}
ansible.builtin.assert:
that:
- 'ini_file_content.content | b64decode | community.general.from_ini(delimiters=["="]) ==
ini_test_dict'
- name: 'Create a file that is not INI formatted: {{ ini_bad_file }}'
ansible.builtin.copy:
dest: '{{ ini_bad_file }}'