Repository: ansible-collections/community.general

Issue:
ini_file module with section to `null` makes ansible 2.15.0 failing
### Summary

When using ini_file module, the [documentation](https://docs.ansible.com/ansible/latest/collections/community/general/ini_file_module.html#parameter-section) state that if the file does not support sections, `null` should be used.

It was working fine in ansible-core 2.14.6, but in ansible-core 2.15.0, it fails with
```
argument 'section' is of type <class 'NoneType'> and we were unable to convert to str: 'None' is not a string and conversion is not allowed
```

### Issue Type

Bug Report

### Component Name

ini_file

### Ansible Version

```console
ansible [core 2.15.0]
  config file = /Users/delovan/git/ansible/ansible.cfg
  configured module search path = ['/Users/delovan/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/delovan/.pyenv/versions/3.9.12/lib/python3.9/site-packages/ansible
  ansible collection location = /Users/delovan/.ansible/collections:/usr/share/ansible/collections:/Users/delovan/git/ansible/collections
  executable location = /Users/delovan/.pyenv/versions/3.9.12/bin/ansible
  python version = 3.9.12 (main, May 16 2022, 11:48:19) [Clang 13.0.0 (clang-1300.0.27.3)] (/Users/delovan/.pyenv/versions/3.9.12/bin/python3.9)
  jinja version = 3.1.2
  libyaml = True
```


### Community.general Version

```console (paste below)
# /Users/delovan/.pyenv/versions/3.9.12/lib/python3.9/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 7.0.1  
```


### Configuration

```console (paste below)
ANY_ERRORS_FATAL(/Users/delovan/git/ansible/ansible.cfg) = True
CACHE_PLUGIN(/Users/delovan/git/ansible/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/Users/delovan/git/ansible/ansible.cfg) = /tmp/facts_cache
CACHE_PLUGIN_TIMEOUT(/Users/delovan/git/ansible/ansible.cfg) = 86400
CALLBACKS_ENABLED(/Users/delovan/git/ansible/ansible.cfg) = ['profile_tasks']
COLLECTIONS_PATHS(/Users/delovan/git/ansible/ansible.cfg) = ['/Users/delovan/.ansible/collections', '/usr/share/ansible/collections', '/Users/delovan/git/ansible/collections']
CONFIG_FILE() = /Users/delovan/git/ansible/ansible.cfg
DEFAULT_ACTION_PLUGIN_PATH(/Users/delovan/git/ansible/ansible.cfg) = ['/Users/delovan/.ansible/plugins/action', '/usr/share/ansible/plugins/action', '/Users/delovan/git/ansible/plug>
DEFAULT_BECOME(/Users/delovan/git/ansible/ansible.cfg) = True
DEFAULT_BECOME_ASK_PASS(/Users/delovan/git/ansible/ansible.cfg) = False
DEFAULT_BECOME_METHOD(/Users/delovan/git/ansible/ansible.cfg) = sudo
DEFAULT_BECOME_USER(/Users/delovan/git/ansible/ansible.cfg) = root
DEFAULT_FORKS(/Users/delovan/git/ansible/ansible.cfg) = 500
DEFAULT_GATHERING(/Users/delovan/git/ansible/ansible.cfg) = smart
DEFAULT_HOST_LIST(/Users/delovan/git/ansible/ansible.cfg) = ['/Users/delovan/git/ansible/inventory']
DEFAULT_JINJA2_NATIVE(/Users/delovan/git/ansible/ansible.cfg) = True
DEFAULT_LOG_PATH(/Users/delovan/git/ansible/ansible.cfg) = /var/log/ansible.log
DEFAULT_REMOTE_USER(/Users/delovan/git/ansible/ansible.cfg) = admin
DEFAULT_ROLES_PATH(/Users/delovan/git/ansible/ansible.cfg) = ['/Users/delovan/.ansible/roles', '/usr/share/ansible/roles', '/etc/ansible/roles', '/Users/delovan/git/ansible/roles']
DEFAULT_STDOUT_CALLBACK(/Users/delovan/git/ansible/ansible.cfg) = debug
DEFAULT_TIMEOUT(/Users/delovan/git/ansible/ansible.cfg) = 60
DEFAULT_VAULT_IDENTITY_LIST(env: ANSIBLE_VAULT_IDENTITY_LIST) = ['@~/.ansible_vault/default_vault_password', 'standalone@~/.ansible_vault/standalone_vault_password', 'andy@~/.ansibl>
DISPLAY_SKIPPED_HOSTS(/Users/delovan/git/ansible/ansible.cfg) = False
HOST_KEY_CHECKING(/Users/delovan/git/ansible/ansible.cfg) = False
INTERPRETER_PYTHON(/Users/delovan/git/ansible/ansible.cfg) = auto_silent
RETRY_FILES_ENABLED(/Users/delovan/git/ansible/ansible.cfg) = False
```


### OS / Environment

MacOS 13

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
- name: Test
  hosts: localhost
  tasks:
    - name: Test
      ini_file:
        path: /Users/delovan/git/ansible/toto
        section: null
        option: test
        value: "test"
        no_extra_spaces: yes
```


### Expected Results

File is written

### Actual Results

```console (paste below)
fatal: [localhost]: FAILED! => {
    "changed": false
}

MSG:

argument 'section' is of type <class 'NoneType'> and we were unable to convert to str: 'None' is not a string and conversion is not allowed
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* [`plugins/modules/ini_file.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/modules/ini_file.py)

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

[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @jpmens @noseka1
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
This is due to a change in ansible-core 2.15. It no longer accepts an explicit `none`/`null` for a string, even for optional ones.

In this case you can work around it by not specifying `section` at all - that is equivalent to `section: null`. If your `null` comes from a template expression, you could replace it with `omit`. That's not optimal, but should get it working for now.
Omitting `section` is an error itself: "missing required arguments: section"
`section` is no longer required, at least not with community.general 6.6.0 or later.
That indeed works if the section is omitted. Documentation should then be updated accordingly to reflect 2.15 changes. Thanks.
huh, I'm also seeing `"missing required arguments: section"` if I omit `section` altogether. Version is ansible 2.15.0
Nevermind, seems to work on 2.15.1

Resolving patch:
diff --git a/plugins/modules/ini_file.py b/plugins/modules/ini_file.py
--- a/plugins/modules/ini_file.py
+++ b/plugins/modules/ini_file.py
@@ -43,8 +43,8 @@
     description:
       - Section name in INI file. This is added if O(state=present) automatically when
         a single value is being set.
-      - If left empty, being omitted, or being set to V(null), the O(option) will be placed before the first O(section).
-      - Using V(null) is also required if the config format does not support sections.
+      - If being omitted, the O(option) will be placed before the first O(section).
+      - Omitting O(section) is also required if the config format does not support sections.
     type: str
   option:
     description:
@@ -171,6 +171,13 @@
       - pepsi
     mode: '0600'
     state: present
+
+- name: Add "beverage=lemon juice" outside a section in specified file
+  community.general.ini_file:
+    path: /etc/conf
+    option: beverage
+    value: lemon juice
+    state: present
 '''
 
 import io


Test patch: