Source code for cis_interface.backwards

r"""This module allows for backward compatibility."""
import sys
import time
import base64
from collections import OrderedDict
from cis_interface.scanf import scanf
_python_version = '%d.%d' % (sys.version_info[0], sys.version_info[1])
PY2 = (sys.version_info[0] == 2)
PY34 = ((sys.version_info[0] == 3) and (sys.version_info[1] == 4))
if PY2:  # pragma: Python 2
    import cPickle as pickle
    import ConfigParser as configparser
    import StringIO as sio
    from __builtin__ import unicode
    import types
    BytesIO = sio.StringIO
    StringIO = sio.StringIO
    file_type = types.FileType
    bytes_type = str
    unicode_type = unicode
    string_type = str
    np_dtype_str = 'S'
    string_types = (str, unicode, bytearray)
    base64_encode = base64.encodestring
    base64_decode = base64.decodestring
else:  # pragma: Python 3
    import pickle
    import configparser
    import io as sio
    BytesIO = sio.BytesIO
    StringIO = sio.StringIO
    file_type = sio.IOBase
    bytes_type = bytes
    unicode_type = str
    string_type = str
    unicode = None
    np_dtype_str = 'S'
    string_types = (bytes, str, bytearray)
    base64_encode = base64.encodebytes
    base64_decode = base64.decodebytes
if sys.version_info >= (3, 3):
    clock_time = time.perf_counter
else:
    clock_time = time.clock


def scanf_bytes(fmt, bytes_line):
    r"""Extract parameters from a bytes object using scanf."""
    if PY2:  # pragma: Python 2
        out_byt = scanf(fmt, bytes_line)
    else:  # pragma: Python 3
        out_str = scanf(as_str(fmt), as_str(bytes_line))
        out_byt = match_stype(bytes_line, out_str, recurse=True,
                              allow_pass=True)
    return out_byt


def assert_str(s):
    r"""Assert that the input is in str type appropriate for the version of
    Python.

    Arguments:
        s (obj): Object to be tested if it is of the proper str class.

    Raises:
        AssertionError: If the object is not in the proper str class.

    """
    assert(isinstance(s, string_type))


def assert_bytes(s):
    r"""Assert that the input is in bytes appropriate for the version of
    Python.

    Arguments:
        s (obj): Object to be tested if it is of the proper bytes class.

    Raises:
        AssertionError: If the object is not in the proper bytes class.

    """
    assert(isinstance(s, bytes_type))


def assert_unicode(s):
    r"""Assert that the input is in unicode appropriate for the version of
    Python.

    Arguments:
        s (obj): Object to be tested if it is of the proper unicode class.

    Raises:
        AssertionError: If the object is not in the proper unicode class.

    """
    assert(isinstance(s, unicode_type))


def recurse_conv(s, func_conv, **kwargs):
    r"""Recurse into list, tuples, or dicts, applying a conversion funciton.

    Args:
        s (object): Object to apply conversion to.
        func_conv (function): Callable conversion function that takes the object
            as input and returns a converted version of it.
        **kwargs: Additional keyword arguments are passed to the conversion
            function.

    Returns:
        object: Converted version of the object.

    Raises:
        TypeError: If the object is not a list, tuple, or dictionary.

    """
    if isinstance(s, list):
        s_out = []
        for i in range(len(s)):
            s_out.append(func_conv(s[i], **kwargs))
    elif isinstance(s, tuple):
        s_out = tuple(func_conv(list(s), **kwargs))
    elif isinstance(s, (dict, OrderedDict)):
        s_out = {}
        for k0 in s.keys():
            k = func_conv(k0, **kwargs)
            s_out[k] = func_conv(s[k0], **kwargs)
    else:
        raise TypeError("Cannot recurse into type: %s" % type(s))
    return s_out


[docs]def as_unicode(s_in, recurse=False, convert_types=None, allow_pass=False): r"""Convert from bytes/unicode/str to unicode. Arguments: s_in (bytes, unicode, str): Object to be converted into unicode. recurse (bool, optional): If True, objects that are lists, tuples, or dicts will be recursed into, converting string elements into unicode. convert_types (list, optional): Python types that should be converted to unicode. Defaults to the string types for the current Python version ([str, unicode, bytearray] in Python 2, [bytes, str, bytearray] otherwise). allow_pass (bool, optional): If True and the provided object is not converted, no error will be raised. Defaults to False and objects that cannot be converted will raise an error. Returns: unicode/str: Unicode version of input (unicode in Python 2, str in Python 3). Raises: TypeError: If supplied type cannot be converted to unicode and allow_pass is False. """ if convert_types is None: convert_types = string_types if isinstance(s_in, convert_types): if PY2: # pragma: Python 2 if isinstance(s_in, (str, bytearray)): s_out = unicode_type(s_in) elif isinstance(s_in, unicode): s_out = s_in else: s_out = unicode_type(s_in) else: # pragma: Python 3 if isinstance(s_in, str): s_out = s_in elif isinstance(s_in, (bytes, bytearray)): s_out = s_in.decode("utf-8") else: s_out = unicode_type(s_in) elif recurse and isinstance(s_in, (list, tuple, dict, OrderedDict)): s_out = recurse_conv(s_in, as_unicode, recurse=True, convert_types=convert_types, allow_pass=allow_pass) elif allow_pass: s_out = s_in else: raise TypeError("Cannot convert type %s to unicode." % type(s_in) + "Must be one of: %s" % str(convert_types)) return s_out
[docs]def as_bytes(s_in, recurse=False, convert_types=None, allow_pass=False): r"""Convert from bytes/unicode/str to a bytes object. Arguments: s_in (str, bytes, unicode): Object to convert to a bytes version. recurse (bool, optional): If True, objects that are lists, tuples, or dicts will be recursed into, converting string elements into unicode. convert_types (list, optional): Python types that should be converted to unicode. Defaults to the string types for the current Python version ([str, unicode, bytearray] in Python 2, [bytes, str, bytearray] otherwise). allow_pass (bool, optional): If True and the provided object is not converted, no error will be raised. Defaults to False and objects that cannot be converted will raise an error. Returns: bytes/str: Bytes version of input (str in Python 2, bytes in Python 3). Raises: TypeError: If supplied type cannot be converted to bytes. """ if convert_types is None: convert_types = string_types if isinstance(s_in, convert_types): if PY2: # pragma: Python 2 if isinstance(s_in, bytearray): s_out = bytes_type(s_in) # In python 2 str is bytes elif isinstance(s_in, str): s_out = s_in elif isinstance(s_in, unicode): s_out = s_in.encode("utf-8") else: s_out = str(s_in) else: # pragma: Python 3 if isinstance(s_in, bytes): s_out = s_in elif isinstance(s_in, bytearray): s_out = bytes_type(s_in) elif isinstance(s_in, str): s_out = s_in.encode("utf-8") else: s_out = as_bytes(str(s_in)) elif recurse and isinstance(s_in, (list, tuple, dict, OrderedDict)): s_out = recurse_conv(s_in, as_bytes, recurse=True, convert_types=convert_types, allow_pass=allow_pass) elif allow_pass: s_out = s_in else: raise TypeError("Cannot convert type %s to bytes." % type(s_in) + "Must be one of: %s" % str(convert_types)) return s_out
[docs]def as_str(s_in, recurse=False, convert_types=None, allow_pass=False): r"""Convert from bytes/unicode/str to a str object. Arguments: s_in (str, bytes, unicode): Object to convert to a str version. recurse (bool, optional): If True, objects that are lists, tuples, or dicts will be recursed into, converting string elements into unicode. convert_types (list, optional): Python types that should be converted to unicode. Defaults to the string types for the current Python version ([str, unicode, bytearray] in Python 2, [bytes, str, bytearray] otherwise). allow_pass (bool, optional): If True and the provided object is not converted, no error will be raised. Defaults to False and objects that cannot be converted will raise an error. Returns: str: Str version of input. Raises: TypeError: If supplied type cannot be converted to str. """ if PY2: # pragma: Python 2 s_out = as_bytes(s_in, recurse=recurse, convert_types=convert_types, allow_pass=allow_pass) else: # pragma: Python 3 s_out = as_unicode(s_in, recurse=recurse, convert_types=convert_types, allow_pass=allow_pass) return s_out
def match_stype(s1, s2, **kwargs): r"""Encodes one string to match the type of the second. Args: s1 (str, bytes, bytearray, unicode): Object that type should be taken from. s2 (str, bytes, bytearray, unicode): Object that should be returned in the type from s1. **kwargs: Additional keyword arguments are passed to the conversion function. Returns: str, bytes, bytearray, unicode: Type matched version of s2. Raises: TypeError: If s1 is not str, bytes, bytearray or unicode. """ if isinstance(s1, string_type): out = as_str(s2, **kwargs) elif isinstance(s1, bytes_type): out = as_bytes(s2, **kwargs) elif isinstance(s1, unicode_type): out = as_unicode(s2, **kwargs) elif isinstance(s1, bytearray): out = bytearray(as_unicode(s2), 'utf-8') if kwargs: # pragma: debug raise RuntimeError("No conversion function for bytearray.") else: raise TypeError("Cannot match s1 type of '%s'" % type(s1)) return out def format_bytes(s, args): r"""Perform format on bytes/str, converting arguments to type of format string to ensure there is no prefix. For Python 3.4, if the format string is bytes, the formats and arguments will be changed to str type before format and then the resulting string will be changed back to bytes. Args: s (str, bytes): Format string. args (tuple): Arguments to be formated using the format string. Returns: str, bytes: Formatted argument string. """ if PY2: # pragma: Python 2 out = s % args else: # pragma: Python 3 is_bytes = isinstance(s, bytes) new_args = [] if PY34 or not is_bytes: converter = as_unicode else: converter = as_bytes for a in args: if isinstance(a, (bytes, str)): new_args.append(converter(a)) else: new_args.append(a) out = converter(s) % tuple(new_args) if is_bytes: out = as_bytes(out) return out def encode_escape(s): r"""Encode escape sequences. Args: s (str): String that should be encoded. Returns: str: Result of encoding escape sequences. """ if PY2: # pragma: Python 2 out = match_stype(s, as_str(s).encode('string-escape')) else: # pragma: Python 3 out = match_stype(s, as_unicode(s).encode('unicode-escape')) return out def decode_escape(s): r"""Decode escape sequences. Args: s (str): String that should be decoded. Returns: str: Result of decoding escape sequences. """ if PY2: # pragma: Python 2 out = match_stype(s, as_bytes(s).decode('string-escape')) else: # pragma: Python 3 out = match_stype(s, as_bytes(s).decode('unicode-escape')) return out # Python 3 version of np.genfromtxt # https://github.com/numpy/numpy/issues/3184 __all__ = ['pickle', 'configparser', 'sio', 'as_str', 'as_bytes', 'as_unicode']