Display parameter name in string conversion warning (#57145)
Add prefix to error message for nested options. This is helpful if a subelement key has the same name as a top level key.
This commit is contained in:
parent
a64418c2b3
commit
6065638e00
2 changed files with 35 additions and 7 deletions
|
@ -0,0 +1,2 @@
|
|||
bugfixes:
|
||||
- add parameter name to warning message when values are converted to strings (https://github.com/ansible/ansible/pull/57145)
|
|
@ -1613,7 +1613,7 @@ class AnsibleModule(object):
|
|||
def safe_eval(self, value, locals=None, include_exceptions=False):
|
||||
return safe_eval(value, locals, include_exceptions)
|
||||
|
||||
def _check_type_str(self, value):
|
||||
def _check_type_str(self, value, param=None, prefix=''):
|
||||
opts = {
|
||||
'error': False,
|
||||
'warn': False,
|
||||
|
@ -1626,12 +1626,22 @@ class AnsibleModule(object):
|
|||
return check_type_str(value, allow_conversion)
|
||||
except TypeError:
|
||||
common_msg = 'quote the entire value to ensure it does not change.'
|
||||
from_msg = '{0!r}'.format(value)
|
||||
to_msg = '{0!r}'.format(to_text(value))
|
||||
|
||||
if param is not None:
|
||||
if prefix:
|
||||
param = '{0}{1}'.format(prefix, param)
|
||||
|
||||
from_msg = '{0}: {1!r}'.format(param, value)
|
||||
to_msg = '{0}: {1!r}'.format(param, to_text(value))
|
||||
|
||||
if self._string_conversion_action == 'error':
|
||||
msg = common_msg.capitalize()
|
||||
raise TypeError(to_native(msg))
|
||||
elif self._string_conversion_action == 'warn':
|
||||
msg = ('The value {0!r} (type {0.__class__.__name__}) in a string field was converted to {1!r} (type string). '
|
||||
'If this does not look like what you expect, {2}').format(value, to_text(value), common_msg)
|
||||
msg = ('The value "{0}" (type {1.__class__.__name__}) was converted to "{2}" (type string). '
|
||||
'If this does not look like what you expect, {3}').format(from_msg, value, to_msg, common_msg)
|
||||
self.warn(to_native(msg))
|
||||
return to_native(value, errors='surrogate_or_strict')
|
||||
|
||||
|
@ -1716,7 +1726,7 @@ class AnsibleModule(object):
|
|||
|
||||
if not self.bypass_checks:
|
||||
self._check_required_arguments(spec, param)
|
||||
self._check_argument_types(spec, param)
|
||||
self._check_argument_types(spec, param, new_prefix)
|
||||
self._check_argument_values(spec, param)
|
||||
|
||||
self._check_required_together(v.get('required_together', None), param)
|
||||
|
@ -1751,9 +1761,16 @@ class AnsibleModule(object):
|
|||
def _handle_elements(self, wanted, param, values):
|
||||
type_checker, wanted_name = self._get_wanted_type(wanted, param)
|
||||
validated_params = []
|
||||
# Get param name for strings so we can later display this value in a useful error message if needed
|
||||
kwargs = {}
|
||||
if wanted_name == 'str':
|
||||
if isinstance(param, string_types):
|
||||
kwargs['param'] = param
|
||||
elif isinstance(param, dict):
|
||||
kwargs['param'] = list(param.keys())[0]
|
||||
for value in values:
|
||||
try:
|
||||
validated_params.append(type_checker(value))
|
||||
validated_params.append(type_checker(value, **kwargs))
|
||||
except (TypeError, ValueError) as e:
|
||||
msg = "Elements value for option %s" % param
|
||||
if self._options_context:
|
||||
|
@ -1762,7 +1779,7 @@ class AnsibleModule(object):
|
|||
self.fail_json(msg=msg)
|
||||
return validated_params
|
||||
|
||||
def _check_argument_types(self, spec=None, param=None):
|
||||
def _check_argument_types(self, spec=None, param=None, prefix=''):
|
||||
''' ensure all arguments have the requested type '''
|
||||
|
||||
if spec is None:
|
||||
|
@ -1780,8 +1797,17 @@ class AnsibleModule(object):
|
|||
continue
|
||||
|
||||
type_checker, wanted_name = self._get_wanted_type(wanted, k)
|
||||
# Get param name for strings so we can later display this value in a useful error message if needed
|
||||
kwargs = {}
|
||||
if wanted_name == 'str':
|
||||
kwargs['param'] = list(param.keys())[0]
|
||||
|
||||
# Get the name of the parent key if this is a nested option
|
||||
if prefix:
|
||||
kwargs['prefix'] = prefix
|
||||
|
||||
try:
|
||||
param[k] = type_checker(value)
|
||||
param[k] = type_checker(value, **kwargs)
|
||||
wanted_elements = v.get('elements', None)
|
||||
if wanted_elements:
|
||||
if wanted != 'list' or not isinstance(param[k], list):
|
||||
|
|
Loading…
Reference in a new issue