Fix json.dumps to do something sensible with sets.

This commit is contained in:
Toshio Kuratomi 2017-05-21 13:56:59 -07:00
parent be4e7a05fa
commit 15104acc00

View file

@ -764,6 +764,13 @@ class AnsibleFallbackNotFound(Exception):
pass pass
class _SetEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Set):
return list(obj)
return super(_SetEncoder, self).default(obj)
class AnsibleModule(object): class AnsibleModule(object):
def __init__(self, argument_spec, bypass_checks=False, no_log=False, def __init__(self, argument_spec, bypass_checks=False, no_log=False,
check_invalid_arguments=True, mutually_exclusive=None, required_together=None, check_invalid_arguments=True, mutually_exclusive=None, required_together=None,
@ -1802,7 +1809,7 @@ class AnsibleModule(object):
return value.strip() return value.strip()
else: else:
if isinstance(value, (list, tuple, dict)): if isinstance(value, (list, tuple, dict)):
return json.dumps(value) return self.jsonify(value)
raise TypeError('%s cannot be converted to a json string' % type(value)) raise TypeError('%s cannot be converted to a json string' % type(value))
def _check_type_raw(self, value): def _check_type_raw(self, value):
@ -2052,14 +2059,14 @@ class AnsibleModule(object):
def jsonify(self, data): def jsonify(self, data):
for encoding in ("utf-8", "latin-1"): for encoding in ("utf-8", "latin-1"):
try: try:
return json.dumps(data, encoding=encoding) return json.dumps(data, encoding=encoding, cls=_SetEncoder)
# Old systems using old simplejson module does not support encoding keyword. # Old systems using old simplejson module does not support encoding keyword.
except TypeError: except TypeError:
try: try:
new_data = json_dict_bytes_to_unicode(data, encoding=encoding) new_data = json_dict_bytes_to_unicode(data, encoding=encoding)
except UnicodeDecodeError: except UnicodeDecodeError:
continue continue
return json.dumps(new_data) return json.dumps(new_data, cls=_SetEncoder)
except UnicodeDecodeError: except UnicodeDecodeError:
continue continue
self.fail_json(msg='Invalid unicode encoding encountered') self.fail_json(msg='Invalid unicode encoding encountered')