mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-24 19:31:26 -07:00
* Move check_type_str() out of basic.py * Move check_type_list() out of basic.py * Move safe_eval() out of basic.py * Move check_type_dict() out of basic.py * Move json importing code to common location * Move check_type_bool() out of basic.py * Move _check_type_int() out of basic.py * Move _check_type_float() out of basic.py * Move _check_type_path() out of basic.py * Move _check_type_raw() out of basic.py * Move _check_type_bytes() out of basic.py * Move _check_type_bits() out of basic.py * Create text.formatters.py Move human_to_bytes, bytes_to_human, and _lenient_lowercase out of basic.py into text.formatters.py Change references in modules to point to function at new location * Move _check_type_jsonarg() out of basic.py * Rename json related functions and put them in common.text.converters Move formatters.py to common.text.formatters.py and update references in modules. * Rework check_type_str() Add allow_conversion option to make the function more self-contained. Move the messaging back to basic.py since those error messages are more relevant to using this function in the context of AnsibleModule and not when using the function in isolation. * Add unit tests for type checking functions * Change _lenient_lowercase to lenient_lowercase per feedback
83 lines
3 KiB
Python
83 lines
3 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright (c) 2019 Ansible Project
|
|
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
__metaclass__ = type
|
|
|
|
import datetime
|
|
import json
|
|
|
|
from itertools import repeat
|
|
|
|
from ansible.module_utils._text import to_bytes, to_native, to_text
|
|
from ansible.module_utils.common._collections_compat import Set
|
|
from ansible.module_utils.six import (
|
|
binary_type,
|
|
iteritems,
|
|
text_type,
|
|
)
|
|
from ansible.module_utils.six.moves import map
|
|
|
|
|
|
def _json_encode_fallback(obj):
|
|
if isinstance(obj, Set):
|
|
return list(obj)
|
|
elif isinstance(obj, datetime.datetime):
|
|
return obj.isoformat()
|
|
raise TypeError("Cannot json serialize %s" % to_native(obj))
|
|
|
|
|
|
def jsonify(data, **kwargs):
|
|
for encoding in ("utf-8", "latin-1"):
|
|
try:
|
|
return json.dumps(data, encoding=encoding, default=_json_encode_fallback, **kwargs)
|
|
# Old systems using old simplejson module does not support encoding keyword.
|
|
except TypeError:
|
|
try:
|
|
new_data = container_to_text(data, encoding=encoding)
|
|
except UnicodeDecodeError:
|
|
continue
|
|
return json.dumps(new_data, default=_json_encode_fallback, **kwargs)
|
|
except UnicodeDecodeError:
|
|
continue
|
|
raise UnicodeError('Invalid unicode encoding encountered')
|
|
|
|
|
|
def container_to_bytes(d, encoding='utf-8', errors='surrogate_or_strict'):
|
|
''' Recursively convert dict keys and values to byte str
|
|
|
|
Specialized for json return because this only handles, lists, tuples,
|
|
and dict container types (the containers that the json module returns)
|
|
'''
|
|
|
|
if isinstance(d, text_type):
|
|
return to_bytes(d, encoding=encoding, errors=errors)
|
|
elif isinstance(d, dict):
|
|
return dict(map(container_to_bytes, iteritems(d), repeat(encoding), repeat(errors)))
|
|
elif isinstance(d, list):
|
|
return list(map(container_to_bytes, d, repeat(encoding), repeat(errors)))
|
|
elif isinstance(d, tuple):
|
|
return tuple(map(container_to_bytes, d, repeat(encoding), repeat(errors)))
|
|
else:
|
|
return d
|
|
|
|
|
|
def container_to_text(d, encoding='utf-8', errors='surrogate_or_strict'):
|
|
"""Recursively convert dict keys and values to byte str
|
|
|
|
Specialized for json return because this only handles, lists, tuples,
|
|
and dict container types (the containers that the json module returns)
|
|
"""
|
|
|
|
if isinstance(d, binary_type):
|
|
# Warning, can traceback
|
|
return to_text(d, encoding=encoding, errors=errors)
|
|
elif isinstance(d, dict):
|
|
return dict(map(container_to_text, iteritems(d), repeat(encoding), repeat(errors)))
|
|
elif isinstance(d, list):
|
|
return list(map(container_to_text, d, repeat(encoding), repeat(errors)))
|
|
elif isinstance(d, tuple):
|
|
return tuple(map(container_to_text, d, repeat(encoding), repeat(errors)))
|
|
else:
|
|
return d
|