diff options
Diffstat (limited to 'lib/ansible/module_utils/_text.py')
-rw-r--r-- | lib/ansible/module_utils/_text.py | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/lib/ansible/module_utils/_text.py b/lib/ansible/module_utils/_text.py index 7dec647580..fe5acf7f27 100644 --- a/lib/ansible/module_utils/_text.py +++ b/lib/ansible/module_utils/_text.py @@ -35,6 +35,13 @@ from ansible.module_utils.six import PY3, text_type, binary_type +import codecs +try: + codecs.lookup_error('surrogateescape') + HAS_SURROGATEESCAPE = True +except LookupError: + HAS_SURROGATEESCAPE = False + def to_bytes(obj, encoding='utf-8', errors=None, nonstring='simplerepr'): """Make sure that a string is a byte string @@ -47,8 +54,22 @@ def to_bytes(obj, encoding='utf-8', errors=None, nonstring='simplerepr'): :kwarg errors: The error handler to use if the text string is not encodable using the specified encoding. Any valid `codecs error handler <https://docs.python.org/2/library/codecs.html#codec-base-classes>`_ - may be specified. On Python3 this defaults to 'surrogateescape'. On - Python2, this defaults to 'replace'. + may be specified. There are two additional error strategies + specifically aimed at helping people to port code: + + :surrogate_or_strict: Will use surrogateescape if it is a valid + handler, otherwise it will use strict + :surrogate_or_replace: Will use surrogateescape if it is a valid + handler, otherwise it will use replace. + + Because surrogateescape was added in Python3 this usually means that + Python3 will use surrogateescape and Python2 will use the fallback + error handler. Note that the code checks for surrogateescape when the + module is imported. If you have a backport of surrogateescape for + python2, be sure to register the error handler prior to importing this + module. + + The default is `surrogate_or_replace` :kwarg nonstring: The strategy to use if a nonstring is specified in ``obj``. Default is 'simplerepr'. Valid values are: @@ -71,11 +92,16 @@ def to_bytes(obj, encoding='utf-8', errors=None, nonstring='simplerepr'): if isinstance(obj, binary_type): return obj - if errors is None: - if PY3: + if errors in (None, 'surrogate_or_replace'): + if HAS_SURROGATEESCAPE: errors = 'surrogateescape' else: errors = 'replace' + elif errors == 'surrogate_or_strict': + if HAS_SURROGATEESCAPE: + errors = 'surrogateescape' + else: + errors = 'strict' if isinstance(obj, text_type): return obj.encode(encoding, errors) @@ -126,6 +152,17 @@ def to_text(obj, encoding='utf-8', errors=None, nonstring='simplerepr'): if isinstance(obj, text_type): return obj + if errors in (None, 'surrogate_or_replace'): + if HAS_SURROGATEESCAPE: + errors = 'surrogateescape' + else: + errors = 'replace' + elif errors == 'surrogate_or_strict': + if HAS_SURROGATEESCAPE: + errors = 'surrogateescape' + else: + errors = 'strict' + if errors is None: if PY3: errors = 'surrogateescape' |