summaryrefslogtreecommitdiff
path: root/lib/ansible/module_utils/_text.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/module_utils/_text.py')
-rw-r--r--lib/ansible/module_utils/_text.py45
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'