Example #1
0
def path_keys(keys):
    """Convert keys used to access an object's path into the standard form: a
    list of keys.
    """
    # pylint: disable=redefined-outer-name
    if pyd.is_string(keys) and ('.' in keys or '[' in keys):
        # This matches "." as delimiter unless it is escaped by "//".
        re_dot_delim = re.compile(r'(?<!\\)(?:\\\\)*\.')

        # Since we can't tell whether a bare number is supposed to be dict key
        # or a list index, we support a special syntax where any string-integer
        # surrounded by brackets is treated as a list index and converted to an
        # integer.
        re_list_index = re.compile(r'\[[\d\]]')

        keys = [
            int(key[1:-1])
            if re_list_index.match(key) else unescape_path_key(key)
            for key in re_dot_delim.split(keys)
        ]
    elif pyd.is_string(keys) or pyd.is_number(keys):
        keys = [keys]
    elif keys is NoValue:
        keys = []

    return keys
Example #2
0
def to_string(obj):
    """Converts an object to string.

    Args:
        obj (mixed): Object to convert.

    Returns:
        str: String representation of `obj`.

    Example:

        >>> to_string(1) == '1'
        True
        >>> to_string(None) == ''
        True
        >>> to_string([1, 2, 3]) == '[1, 2, 3]'
        True
        >>> to_string('a') == 'a'
        True

    .. versionadded:: 2.0.0

    .. versionchanged:: 3.0.0
        Convert ``None`` to empty string.
    """
    if pyd.is_string(obj):
        res = obj
    elif obj is None:
        res = ''
    else:
        res = text_type(obj)
    return res
Example #3
0
def splice(array, index, how_many=None, *items):
    """Modify the contents of `array` by inserting elements starting at `index`
    and removing `how_many` number of elements after `index`.

    Args:
        array (list|str): List to splice.
        index (int): Index to splice at.
        how_many (int, optional): Number of items to remove starting at
            `index`. If ``None`` then all items after `index` are removed.
            Defaults to ``None``.
        items (mixed): Elements to insert starting at `index`. Each item is
            inserted in the order given.

    Returns:
        list|str: The removed elements of `array` or the spliced string.

    Warning:
        `array` is modified in place if ``list``.

    Example:

        >>> array = [1, 2, 3, 4]
        >>> splice(array, 1)
        [2, 3, 4]
        >>> array
        [1]
        >>> array = [1, 2, 3, 4]
        >>> splice(array, 1, 2)
        [2, 3]
        >>> array
        [1, 4]
        >>> array = [1, 2, 3, 4]
        >>> splice(array, 1, 2, 0, 0)
        [2, 3]
        >>> array
        [1, 0, 0, 4]

    .. versionadded:: 2.2.0

    .. versionchanged:: 3.0.0
        Support string splicing.
    """
    if how_many is None:
        how_many = len(array) - index

    is_string = pyd.is_string(array)

    if is_string:
        array = list(array)

    removed = array[index:index + how_many]
    del array[index:index + how_many]

    for item in reverse(items):
        array.insert(index, item)

    if is_string:
        return ''.join(array)
    else:
        return removed
Example #4
0
def to_string(obj):
    """
    Converts an object to string.

    Args:
        obj (mixed): Object to convert.

    Returns:
        str: String representation of `obj`.

    Example:

        >>> to_string(1) == '1'
        True
        >>> to_string(None) == ''
        True
        >>> to_string([1, 2, 3]) == '[1, 2, 3]'
        True
        >>> to_string('a') == 'a'
        True

    .. versionadded:: 2.0.0

    .. versionchanged:: 3.0.0
        Convert ``None`` to empty string.
    """
    if pyd.is_string(obj):
        res = obj
    elif obj is None:
        res = ""
    else:
        res = text_type(obj)
    return res
Example #5
0
def splice(array, index, how_many=None, *items):
    """Modify the contents of `array` by inserting elements starting at `index`
    and removing `how_many` number of elements after `index`.

    Args:
        array (list|str): List to splice.
        index (int): Index to splice at.
        how_many (int, optional): Number of items to remove starting at
            `index`. If ``None`` then all items after `index` are removed.
            Defaults to ``None``.
        items (mixed): Elements to insert starting at `index`. Each item is
            inserted in the order given.

    Returns:
        list|str: The removed elements of `array` or the spliced string.

    Warning:
        `array` is modified in place if ``list``.

    Example:

        >>> array = [1, 2, 3, 4]
        >>> splice(array, 1)
        [2, 3, 4]
        >>> array
        [1]
        >>> array = [1, 2, 3, 4]
        >>> splice(array, 1, 2)
        [2, 3]
        >>> array
        [1, 4]
        >>> array = [1, 2, 3, 4]
        >>> splice(array, 1, 2, 0, 0)
        [2, 3]
        >>> array
        [1, 0, 0, 4]

    .. versionadded:: 2.2.0

    .. versionchanged:: 3.0.0
        Support string splicing.
    """
    if how_many is None:
        how_many = len(array) - index

    is_string = pyd.is_string(array)

    if is_string:
        array = list(array)

    removed = array[index:index + how_many]
    del array[index:index + how_many]

    for item in reverse(items):
        array.insert(index, item)

    if is_string:
        return ''.join(array)
    else:
        return removed
Example #6
0
def base_clone(value, is_deep=False, customizer=None, key=None, _cloned=False):
    """Base clone function that supports deep clone and customizer callback."""
    clone_by = copy.deepcopy if is_deep else copy.copy
    result = None

    if callable(customizer) and not _cloned:
        argcount = getargcount(customizer, maxargs=4)
        cbk = partial(callit, customizer, argcount=argcount)
    elif _cloned:
        cbk = customizer
    else:
        cbk = None

    if cbk:
        result = cbk(value, key, value)

    if result is not None:
        return result

    if not _cloned:
        result = clone_by(value)
    else:
        result = value

    if cbk and not pyd.is_string(value) and not isinstance(value, bytes):
        for key, subvalue in iterator(value):
            if is_deep:
                val = base_clone(subvalue, is_deep, cbk, key, _cloned=True)
            else:
                val = cbk(subvalue, key, value)

            if val is not None:
                result[key] = val

    return result
Example #7
0
def truncate(text, length=30, omission='...', separator=None):
    """Truncates `text` if it is longer than the given maximum string length.
    The last characters of the truncated string are replaced with the omission
    string which defaults to ``...``.

    Args:
        text (str): String to truncate.
        length (int, optional): Maximum string length. Defaults to ``30``.
        omission (str, optional): String to indicate text is omitted.
        separator (mixed, optional): Separator pattern to truncate to.

    Returns:
        str: Truncated string.

    Example:

        >>> truncate('hello world', 5)
        'he...'
        >>> truncate('hello world', 5, '..')
        'hel..'
        >>> truncate('hello world', 10)
        'hello w...'
        >>> truncate('hello world', 10, separator=' ')
        'hello...'

    See Also:
        - :func:`truncate` (main definition)
        - :func:`trunc` (alias)

    .. versionadded:: 1.1.0

    .. versionchanged:: 3.0.0
        Made :func:`truncate` main function definition and added :func:`trunc`
        as alias.
    """
    text = pyd.to_string(text)

    if len(text) <= length:
        return text

    omission_len = len(omission)
    text_len = length - omission_len
    text = text[:text_len]

    trunc_len = len(text)

    if pyd.is_string(separator):
        trunc_len = text.rfind(separator)
    elif pyd.is_re(separator):
        last = None
        for match in separator.finditer(text):
            last = match

        if last is not None:
            trunc_len = last.start()

    return text[:trunc_len] + omission
Example #8
0
def truncate(text, length=30, omission="...", separator=None):
    """Truncates `text` if it is longer than the given maximum string length.
    The last characters of the truncated string are replaced with the omission
    string which defaults to ``...``.

    Args:
        text (str): String to truncate.
        length (int, optional): Maximum string length. Defaults to ``30``.
        omission (str, optional): String to indicate text is omitted.
        separator (mixed, optional): Separator pattern to truncate to.

    Returns:
        str: Truncated string.

    Example:

        >>> truncate('hello world', 5)
        'he...'
        >>> truncate('hello world', 5, '..')
        'hel..'
        >>> truncate('hello world', 10)
        'hello w...'
        >>> truncate('hello world', 10, separator=' ')
        'hello...'

    See Also:
        - :func:`truncate` (main definition)
        - :func:`trunc` (alias)

    .. versionadded:: 1.1.0

    .. versionchanged:: 3.0.0
        Made :func:`truncate` main function definition and added :func:`trunc`
        as alias.
    """
    text = pyd.to_string(text)

    if len(text) <= length:
        return text

    omission_len = len(omission)
    text_len = length - omission_len
    text = text[:text_len]

    trunc_len = len(text)

    if pyd.is_string(separator):
        trunc_len = text.rfind(separator)
    elif pyd.is_re(separator):
        last = None
        for match in separator.finditer(text):
            last = match

        if last is not None:
            trunc_len = last.start()

    return text[:trunc_len] + omission
Example #9
0
def to_path_tokens(value):
    """Parse `value` into :class:`PathToken` objects."""
    if pyd.is_string(value) and ('.' in value or '[' in value):
        # Since we can't tell whether a bare number is supposed to be dict key
        # or a list index, we support a special syntax where any string-integer
        # surrounded by brackets is treated as a list index and converted to an
        # integer.
        keys = [PathToken(int(key[1:-1]), default_factory=list)
                if RE_PATH_LIST_INDEX.match(key)
                else PathToken(unescape_path_key(key), default_factory=dict)
                for key in filter(None, RE_PATH_KEY_DELIM.split(value))]
    elif pyd.is_string(value) or pyd.is_number(value):
        keys = [PathToken(value, default_factory=dict)]
    elif value is NoValue:
        keys = []
    else:
        keys = value

    return keys
Example #10
0
def to_path_tokens(value):
    """Parse `value` into :class:`PathToken` objects."""
    if pyd.is_string(value) and ('.' in value or '[' in value):
        # Since we can't tell whether a bare number is supposed to be dict key
        # or a list index, we support a special syntax where any string-integer
        # surrounded by brackets is treated as a list index and converted to an
        # integer.
        keys = [PathToken(int(key[1:-1]), default_factory=list)
                if RE_PATH_LIST_INDEX.match(key)
                else PathToken(unescape_path_key(key), default_factory=dict)
                for key in filter(None, RE_PATH_KEY_DELIM.split(value))]
    elif pyd.is_string(value) or pyd.is_number(value):
        keys = [PathToken(value, default_factory=dict)]
    elif value is NoValue:
        keys = []
    else:
        keys = value

    return keys
Example #11
0
def path_keys(keys):
    """Convert keys used to access an object's path into the standard form: a
    list of keys.
    """
    # pylint: disable=redefined-outer-name
    if pyd.is_string(keys) and ('.' in keys or '[' in keys):
        # Since we can't tell whether a bare number is supposed to be dict key
        # or a list index, we support a special syntax where any string-integer
        # surrounded by brackets is treated as a list index and converted to an
        # integer.
        keys = [int(key[1:-1]) if RE_PATH_LIST_INDEX.match(key)
                else unescape_path_key(key)
                for key in filter(None, RE_PATH_KEY_DELIM.split(keys))]
    elif pyd.is_string(keys) or pyd.is_number(keys):
        keys = [keys]
    elif keys is NoValue:
        keys = []

    return keys
Example #12
0
def to_boolean(obj, true_values=('true', '1'), false_values=('false', '0')):
    """Convert `obj` to boolean. This is not like the builtin ``bool``
    function. By default commonly considered strings values are converted to
    their boolean equivalent, i.e., ``'0'`` and ``'false'`` are converted to
    ``False`` while ``'1'`` and ``'true'`` are converted to ``True``. If a
    string value is provided that isn't recognized as having a common boolean
    conversion, then the returned value is ``None``. Non-string values of `obj`
    are converted using ``bool``. Optionally, `true_values` and `false_values`
    can be overridden but each value must be a string.

    Args:
        obj (mixed): Object to convert.
        true_values (tuple, optional): Values to consider ``True``. Each value
            must be a string. Comparision is case-insensitive. Defaults to
            ``('true', '1')``.
        false_values (tuple, optional): Values to consider ``False``. Each
            value must be a string. Comparision is case-insensitive. Defaults
            to ``('false', '0')``.

    Returns:
        bool: Boolean value of `obj`.

    Example:

        >>> to_boolean('true')
        True
        >>> to_boolean('1')
        True
        >>> to_boolean('false')
        False
        >>> to_boolean('0')
        False
        >>> assert to_boolean('a') is None

    .. versionadded:: 3.0.0
    """
    if pyd.is_string(obj):
        obj = obj.strip()

        def boolean_match(text, vals):
            if text.lower() in [val.lower() for val in vals]:
                return True
            else:
                return re.match('|'.join(vals), text)

        if true_values and boolean_match(obj, true_values):
            value = True
        elif false_values and boolean_match(obj, false_values):
            value = False
        else:
            value = None
    else:
        value = bool(obj)

    return value
Example #13
0
def to_boolean(obj, true_values=('true', '1'), false_values=('false', '0')):
    """Convert `obj` to boolean. This is not like the builtin ``bool``
    function. By default commonly considered strings values are converted to
    their boolean equivalent, i.e., ``'0'`` and ``'false'`` are converted to
    ``False`` while ``'1'`` and ``'true'`` are converted to ``True``. If a
    string value is provided that isn't recognized as having a common boolean
    conversion, then the returned value is ``None``. Non-string values of `obj`
    are converted using ``bool``. Optionally, `true_values` and `false_values`
    can be overridden but each value must be a string.

    Args:
        obj (mixed): Object to convert.
        true_values (tuple, optional): Values to consider ``True``. Each value
            must be a string. Comparision is case-insensitive. Defaults to
            ``('true', '1')``.
        false_values (tuple, optional): Values to consider ``False``. Each
            value must be a string. Comparision is case-insensitive. Defaults
            to ``('false', '0')``.

    Returns:
        bool: Boolean value of `obj`.

    Example:

        >>> to_boolean('true')
        True
        >>> to_boolean('1')
        True
        >>> to_boolean('false')
        False
        >>> to_boolean('0')
        False
        >>> assert to_boolean('a') is None

    .. versionadded:: 3.0.0
    """
    if pyd.is_string(obj):
        obj = obj.strip()

        def boolean_match(text, vals):  # pylint: disable=missing-docstring
            if text.lower() in [val.lower() for val in vals]:
                return True
            else:
                return re.match('|'.join(vals), text)

        if true_values and boolean_match(obj, true_values):
            value = True
        elif false_values and boolean_match(obj, false_values):
            value = False
        else:
            value = None
    else:
        value = bool(obj)

    return value
Example #14
0
    def op(value, comparable, flags=0):
        if pydash.is_string(comparable):
            pattern = re.compile(comparable, flags)
        else:
            pattern = comparable

        try:
            match = bool(pattern.match(value))
        except (TypeError, ValueError):
            match = False

        return match
Example #15
0
def valid_table_name(event):
    result = get(event, 'tableName')
    if result is None:
        return ['Invalid tableName, none found in event.']

    if is_string(result) == False:
        return ['Invalid tableName, tableName is not a String.']

    if result == '':
        return ['Invalid tableName, tableName is blank.']

    return []
Example #16
0
    def op(value, comparable, flags=0):
        if pydash.is_string(comparable):
            pattern = re.compile(comparable, flags)
        else:
            pattern = comparable

        try:
            match = bool(pattern.match(value))
        except (TypeError, ValueError):
            match = False

        return match
Example #17
0
 def add(self, data_name, data_v):
     '''
     Add a data to a data space, e.g. data actions collected per body, per agent, from agent_space, with AEB shape projected on a-axis, added to action_space.
     Could also be a shortcut to do batch add data_v_1, data_v_2, ...
     @param {str|[str]} data_name
     @param {[x: [yb_idx:[body_v]]} data_v, where x, y could be a, e interchangeably.
     @returns {DataSpace} data_space (aeb is implied)
     '''
     if ps.is_string(data_name):
         data_space = self.data_spaces[data_name]
         data_space.add(data_v)
         return data_space
     else:
         return [self.add(d_name, d_v) for d_name, d_v in zip(data_name, data_v)]
Example #18
0
 def add(self, data_name, data_v):
     '''
     Add a data to a data space, e.g. data actions collected per body, per agent, from agent_space, with AEB shape projected on a-axis, added to action_space.
     Could also be a shortcut to do batch add data_v_1, data_v_2, ...
     @param {str|[str]} data_name
     @param {[x: [yb_idx:[body_v]]} data_v, where x, y could be a, e interchangeably.
     @returns {DataSpace} data_space (aeb is implied)
     '''
     if ps.is_string(data_name):
         data_space = self.data_spaces[data_name]
         data_space.add(data_v)
         return data_space
     else:
         return [self.add(d_name, d_v) for d_name, d_v in zip(data_name, data_v)]
Example #19
0
def valid_table_operation(event):
    result = get(event, 'tableOperation')
    if result is None:
        return ['Invalid tableOperation, none found in event.']

    if is_string(result) == False:
        return ['Invalid tableOperation, tableOperation is not a String.']

    lower_result = result.lower()
    print("lower_result:", lower_result)
    if lower_result != 'create' and lower_result != 'delete' and lower_result != 'deleteandcreate':
        return ['Invalid tableOperation, tableOperation is supposed to equal create, delete, or deleteandcreate.']

    return []
Example #20
0
def path_keys(keys):
    """Convert keys used to access an object's path into the standard form: a
    list of keys.
    """
    # pylint: disable=redefined-outer-name
    if pyd.is_string(keys) and ('.' in keys or '[' in keys):
        # This matches "." as delimiter unless it is escaped by "//".
        re_dot_delim = re.compile(r'(?<!\\)(?:\\\\)*\.')

        # Since we can't tell whether a bare number is supposed to be dict key
        # or a list index, we support a special syntax where any string-integer
        # surrounded by brackets is treated as a list index and converted to an
        # integer.
        re_list_index = re.compile(r'\[[\d\]]')

        keys = [int(key[1:-1]) if re_list_index.match(key)
                else unescape_path_key(key)
                for key in re_dot_delim.split(keys)]
    elif pyd.is_string(keys) or pyd.is_number(keys):
        keys = [keys]
    elif keys is NoValue:
        keys = []

    return keys
Example #21
0
def parse_int(value, radix=None):
    """
    Converts the given `value` into an integer of the specified `radix`. If `radix` is falsey, a
    radix of ``10`` is used unless the `value` is a hexadecimal, in which case a radix of 16 is
    used.

    Args:
        value (mixed): Value to parse.
        radix (int, optional): Base to convert to.

    Returns:
        mixed: Integer if parsable else ``None``.

    Example:

        >>> parse_int('5')
        5
        >>> parse_int('12', 8)
        10
        >>> parse_int('x') is None
        True

    .. versionadded:: 1.0.0
    """
    if not radix and pyd.is_string(value):
        try:
            # Check if value is hexadcimal and if so use base-16 conversion.
            int(value, 16)
        except ValueError:
            pass
        else:
            radix = 16

    if not radix:
        radix = 10

    try:
        # NOTE: Must convert value to string when supplying radix to int(). Dropping radix arg when
        # 10 is needed to allow floats to parse correctly.
        args = (value, ) if radix == 10 else (to_string(value), radix)
        parsed = int(*args)
    except (ValueError, TypeError):
        parsed = None

    return parsed
Example #22
0
def parse_int(value, radix=None):
    """Converts the given `value` into an integer of the specified `radix`. If
    `radix` is falsey, a radix of ``10`` is used unless the `value` is a
    hexadecimal, in which case a radix of 16 is used.

    Args:
        value (mixed): Value to parse.
        radix (int, optional): Base to convert to.

    Returns:
        mixed: Integer if parsable else ``None``.

    Example:

        >>> parse_int('5')
        5
        >>> parse_int('12', 8)
        10
        >>> parse_int('x') is None
        True

    .. versionadded:: 1.0.0
    """
    if not radix and pyd.is_string(value):
        try:
            # Check if value is hexadcimal and if so use base-16 conversion.
            int(value, 16)
        except ValueError:
            pass
        else:
            radix = 16

    if not radix:
        radix = 10

    try:
        # NOTE: Must convert value to string when supplying radix to int().
        # Dropping radix arg when 10 is needed to allow floats to parse
        # correctly.
        args = (value,) if radix == 10 else (to_string(value), radix)
        parsed = int(*args)
    except (ValueError, TypeError):
        parsed = None

    return parsed
Example #23
0
def base_clone(value, is_deep=False, customizer=None, key=None, obj=None,
               _cloned=False):
    """Base clone function that supports deep clone and customizer callback."""
    clone_by = copy.deepcopy if is_deep else copy.copy
    result = None

    if callable(customizer) and not _cloned:
        argcount = getargcount(customizer, maxargs=4)
        cbk = partial(callit, customizer, argcount=argcount)
    elif _cloned:
        cbk = customizer
    else:
        cbk = None

    if cbk:
        result = cbk(value, key, value)

    if result is not None:
        return result

    if not _cloned:
        result = clone_by(value)
    else:
        result = value

    if cbk and not pyd.is_string(value) and not isinstance(value, bytes):
        for key, subvalue in iterator(value):
            if is_deep:
                val = base_clone(subvalue, is_deep, cbk, key, value,
                                 _cloned=True)
            else:
                val = cbk(subvalue, key, value)

            if val is not None:
                result[key] = val

    return result
Example #24
0
def test_get_ts():
    ts = util.get_ts()
    assert _.is_string(ts)
    assert util.RE_FILE_TS.match(ts)
Example #25
0
def test_is_string(case, expected):
    assert _.is_string(case) == expected
Example #26
0
def test_get_ts():
    ts = util.get_ts()
    assert ps.is_string(ts)
    assert util.RE_FILE_TS.match(ts)
Example #27
0
def arg_needs_resource(arg: str, resource: str) -> bool:
    """
    checks if an arg needs a mongo instance
    """
    return pydash.is_string(arg) and resource in arg
Example #28
0
def test_get_timestamp():
    timestamp = util.get_timestamp()
    assert _.is_string(timestamp)
    assert util.RE_FILE_TS.match(timestamp)