### Summary

When creating a new plugin, if an argument uses a list of pre-defined `choices`, even if an empty string ('') is not defined in the selection, it is accepted as a valid value in the playbook.

The problem is that `diff_list` is evaluated to "", and thus, the test that should raise an error evaluates to false (`lib/ansible/module_utils/common/parametres.py`):
https://github.com/ansible/ansible/blob/36121aeee7812e7f37dd49a64c0dbf9cf741878f/lib/ansible/module_utils/common/parameters.py#L653..L660

### Issue Type

Bug Report

### Component Name

Any plugin that uses `choices` in one of its parameters.

### Ansible Version

```console
$ ansible --version
ansible [core 2.12.2]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/rjeffman/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.10/site-packages/ansible
  ansible collection location = /home/rjeffman/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.2 (main, Jan 17 2022, 00:00:00) [GCC 11.2.1 20211203 (Red Hat 11.2.1-7)]
  jinja version = 3.0.1
  libyaml = True
```


### Configuration

```console
$ ansible-config dump --only-changed
$
```


### OS / Environment

Any.

### Steps to Reproduce

If you have a plugin (e.g: `myplugin`) where `argument_spec` list a parameter defined like:
```
ch_param=dict(type="list", choices=["A", "B", "C"]),
``` 

Then the following task would not raise an error:
```yaml (paste below)
- myplugin:
    ch_param: ""
```


### Expected Results

If a value provide by a parameter with a list of valid choices, it is expected that any value outside of this list would raise an error.

### Actual Results

```console
No error is reported by Ansible.
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct
"""Sanitize the keys in a container object by removing ``no_log`` values from key names.
    This is a companion function to the :func:`remove_values` function. Similar to that function,
    we make use of ``deferred_removals`` to avoid hitting maximum recursion depth in cases of
    large data structures.
    :arg obj: The container object to sanitize. Non-container objects are returned unmodified.
    :arg no_log_strings: A set of string values we do not want logged.
    :kwarg ignore_keys: A set of string values of keys to not sanitize.
    :returns: An object with sanitized keys.
    """
    deferred_removals = deque()
    no_log_strings = [to_native(s, errors='surrogate_or_strict') for s in no_log_strings]
    new_value = _sanitize_keys_conditions(obj, no_log_strings, ignore_keys, deferred_removals)
    while deferred_removals:
        old_data, new_data = deferred_removals.popleft()
        if isinstance(new_data, Mapping):
            for old_key, old_elem in old_data.items():
                if old_key in ignore_keys or old_key.startswith('_ansible'):
                    new_data[old_key] = _sanitize_keys_conditions(old_elem, no_log_strings, ignore_keys, deferred_removals)
                else:
                    
                    
                    new_key = _remove_values_conditions(old_key, no_log_strings, None)
                    new_data[new_key] = _sanitize_keys_conditions(old_elem, no_log_strings, ignore_keys, deferred_removals)
        else:
            for elem in old_data:
                new_elem = _sanitize_keys_conditions(elem, no_log_strings, ignore_keys, deferred_removals)
                if isinstance(new_data, MutableSequence):
                    new_data.append(new_elem)
                elif isinstance(new_data, MutableSet):
                    new_data.add(new_elem)