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):
|
def safe_eval(self, value, locals=None, include_exceptions=False):
|
||||||
return safe_eval(value, locals, include_exceptions)
|
return safe_eval(value, locals, include_exceptions)
|
||||||
|
|
||||||
def _check_type_str(self, value):
|
def _check_type_str(self, value, param=None, prefix=''):
|
||||||
opts = {
|
opts = {
|
||||||
'error': False,
|
'error': False,
|
||||||
'warn': False,
|
'warn': False,
|
||||||
|
@ -1626,12 +1626,22 @@ class AnsibleModule(object):
|
||||||
return check_type_str(value, allow_conversion)
|
return check_type_str(value, allow_conversion)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
common_msg = 'quote the entire value to ensure it does not change.'
|
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':
|
if self._string_conversion_action == 'error':
|
||||||
msg = common_msg.capitalize()
|
msg = common_msg.capitalize()
|
||||||
raise TypeError(to_native(msg))
|
raise TypeError(to_native(msg))
|
||||||
elif self._string_conversion_action == 'warn':
|
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). '
|
msg = ('The value "{0}" (type {1.__class__.__name__}) was converted to "{2}" (type string). '
|
||||||
'If this does not look like what you expect, {2}').format(value, to_text(value), common_msg)
|
'If this does not look like what you expect, {3}').format(from_msg, value, to_msg, common_msg)
|
||||||
self.warn(to_native(msg))
|
self.warn(to_native(msg))
|
||||||
return to_native(value, errors='surrogate_or_strict')
|
return to_native(value, errors='surrogate_or_strict')
|
||||||
|
|
||||||
|
@ -1716,7 +1726,7 @@ class AnsibleModule(object):
|
||||||
|
|
||||||
if not self.bypass_checks:
|
if not self.bypass_checks:
|
||||||
self._check_required_arguments(spec, param)
|
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_argument_values(spec, param)
|
||||||
|
|
||||||
self._check_required_together(v.get('required_together', None), 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):
|
def _handle_elements(self, wanted, param, values):
|
||||||
type_checker, wanted_name = self._get_wanted_type(wanted, param)
|
type_checker, wanted_name = self._get_wanted_type(wanted, param)
|
||||||
validated_params = []
|
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:
|
for value in values:
|
||||||
try:
|
try:
|
||||||
validated_params.append(type_checker(value))
|
validated_params.append(type_checker(value, **kwargs))
|
||||||
except (TypeError, ValueError) as e:
|
except (TypeError, ValueError) as e:
|
||||||
msg = "Elements value for option %s" % param
|
msg = "Elements value for option %s" % param
|
||||||
if self._options_context:
|
if self._options_context:
|
||||||
|
@ -1762,7 +1779,7 @@ class AnsibleModule(object):
|
||||||
self.fail_json(msg=msg)
|
self.fail_json(msg=msg)
|
||||||
return validated_params
|
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 '''
|
''' ensure all arguments have the requested type '''
|
||||||
|
|
||||||
if spec is None:
|
if spec is None:
|
||||||
|
@ -1780,8 +1797,17 @@ class AnsibleModule(object):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
type_checker, wanted_name = self._get_wanted_type(wanted, k)
|
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:
|
try:
|
||||||
param[k] = type_checker(value)
|
param[k] = type_checker(value, **kwargs)
|
||||||
wanted_elements = v.get('elements', None)
|
wanted_elements = v.get('elements', None)
|
||||||
if wanted_elements:
|
if wanted_elements:
|
||||||
if wanted != 'list' or not isinstance(param[k], list):
|
if wanted != 'list' or not isinstance(param[k], list):
|
||||||
|
|
Loading…
Reference in a new issue