import six
import locale


def _decode_preferred_encoding(s):
    """
    Decode the supplied byte string using the preferred encoding for
    the locale (`locale.getpreferredencoding`) or, if the default
    encoding is invalid, fall back first on utf-8, then on latin-1 if
    the message cannot be decoded with utf-8.
    """

    if six.PY3 and isinstance(s, bytes):
        enc = locale.getpreferredencoding()
        try:
            try:
                return s.decode(enc)
            except LookupError:
                enc = 'utf-8'
            return s.decode(enc)
        except UnicodeDecodeError:
            return s.decode('latin-1', 'replace')
    return s