1import six
2
3text_type = six.text_type
4string_types = six.string_types
5binary_type = six.binary_type
6
7
8def safe_decode(value, encoding='utf-8', errors='strict'):
9    if isinstance(value, text_type):
10        return value
11
12    if isinstance(value, (string_types, binary_type)):
13        return value.decode(encoding, errors)
14    else:
15        return binary_type(value).decode(encoding, errors)
16
17
18def safe_encode(value, incoming=None, encoding='utf-8', errors='strict'):
19    if not isinstance(value, (string_types, binary_type)):
20        return binary_type(value)
21
22    if isinstance(value, text_type):
23        return value.encode(encoding, errors)
24    else:
25        if hasattr(incoming, 'lower'):
26            incoming = incoming.lower()
27        if hasattr(encoding, 'lower'):
28            encoding = encoding.lower()
29
30        if value and encoding != incoming:
31            value = safe_decode(value, encoding, errors)
32            return value.encode(encoding, errors)
33        else:
34            return value
35