def safe_encode(u, encoding=None): '''Similar to unicode `encode` method returning bytes. Encodes `u` using the given `encoding`, or determining one from the system. Returning type is always `bytes`; but in python 2.x is also `str`. .. versionadded:: 1.1.3 ''' # TODO: This is not nice for Python 3, bytes is not valid string any more # See :func:`json.encoder.py_encode_basestring_ascii` of Python 2.x from xoutil.eight import string_types, text_type if isinstance(u, bytes): return u else: encoding = force_encoding(encoding) try: try: if isinstance(u, string_types): # In Python 2.x bytes does not allows an encoding argument. return bytes(u) else: return text_type(u).encode(encoding, 'replace') except: return text_type(u).encode(encoding, 'replace') except LookupError: return safe_encode(u)
def safe_decode(s, encoding=None): '''Similar to bytes `decode` method returning unicode. Decodes `s` using the given `encoding`, or determining one from the system. Returning type depend on python version; if 2.x is `unicode` if 3.x `str`. .. versionadded:: 1.1.3 ''' from xoutil.eight import text_type if isinstance(s, text_type): return s else: encoding = force_encoding(encoding) try: # In Python 3 str(b'm') returns the string "b'm'" and not just "m", # this fixes this. return text_type(s, encoding, 'replace') except LookupError: # The provided enconding is not know, try with no encoding. return safe_decode(s) except: # For numbers and other stuff. return text_type(s)
def bytes_coerce(arg): """Encode an unicode string (or any object) returning a bytes buffer. Uses the defined `encoding` system value. In Python 2.x `bytes` coincide with `str` type, in Python 3 `str` uses unicode and `str` is different to `bytes`. There are differences if you want to obtain a buffer in Python 2.x and Python 3; for example, the following code obtain different results:: >>> ba = bytes([65, 66, 67]) In Python 2.x is obtained the string ``"[65, 66, 67]"`` and in Python 3 ``b"ABC"``. This function normalize these differences. Name is used in named objects, see `name_coerce`:func: for more information. See `str_coerce`:func: to coerce to standard string type, `bytes` in Python 2.x and unicode (`str`) in Python 3. Always returns the `bytes` type. .. versionadded:: 1.7.0 """ from array import array from . import Invalid from xoutil.eight import text_type aux = name_coerce(arg) if aux is not Invalid: arg = aux if isinstance(arg, bytes): return arg elif isinstance(arg, bytearray): return bytes(arg) elif isinstance(arg, memoryview): return arg.tobytes() elif isinstance(arg, array): try: arg = arg.tounicode() except BaseException: try: return bytes(bytearray(arg.tolist())) except BaseException: arg = text_type(arg) res = encode_coerce(arg) return encode_coerce(text_type(arg)) if res is Invalid else res
def unicode_coerce(arg): """Decode a buffer or any object returning unicode text. Uses the defined `encoding` system value. In Python 2.x unicode has a special type different to `str` but in Python 3 coincide with `str` type. Name is used in named objects, see `name_coerce`:func: for more information. See `str_coerce`:func: to coerce to standard string type, `bytes` in Python 2.x and unicode (`str`) in Python 3. .. versionadded:: 1.7.0 """ from array import array from . import Invalid from xoutil.eight import text_type aux = name_coerce(arg) if aux is not Invalid: arg = aux if isinstance(arg, text_type): return arg elif isinstance(arg, bytearray): arg = bytes(arg) elif isinstance(arg, memoryview): arg = arg.tobytes() elif isinstance(arg, array): try: return arg.tounicode() except BaseException: try: arg = bytes(bytearray(arg.tolist())) except BaseException: arg = str(arg) if str is text_type: return arg res = decode_coerce(arg) return text_type(arg) if res is Invalid else res
def __call__(self, mapping): from xoutil.eight import text_type return text_type(eval(self.key, mapping))