예제 #1
0
def test_istext():
    assert validate.is_text('test') is True
    assert validate.is_text('123') is True
    assert validate.is_text('') is True
    assert validate.is_text('', False) is False
    assert validate.is_text(None) is False
    assert validate.is_text(True) is False
    assert validate.is_text(' ') is True
    assert validate.is_text(' ', False) is True
    assert validate.is_text(1) is False
예제 #2
0
def unquote(text: str) -> str:
    """
    Strips trailing quotes from a text string and returns it.

    :param text:    The string to strip.
    """
    _vld.pass_if(_vld.is_text(text), TypeError,
                 "'text' attribute must be a string (got {!r})".format(text))
    return text.strip('\'"`')
예제 #3
0
def capitalize(text: str) -> str:
    """
    Function that works similar to the built-in string method :func:`str.capitalize`,
    except that it only makes the first character uppercase, and leaves the other characters unchanged.

    :param text:    The string to capitalize.
    """
    _vld.pass_if(_vld.is_text(text), TypeError,
                 "'text' attribute must be a string (got {!r})".format(text))
    if len(text) < 2:
        return text.upper()
    return f'{text[0].upper()}{text[1:]}'
예제 #4
0
파일: paths.py 프로젝트: geocom-gis/gpf3
    def __init__(self, path, base=None):
        _vld.pass_if(_vld.is_text(path, False), TypeError,
                     "Attribute 'path' should be a non-empty string")
        self._path = _os.path.normpath(path)

        if base:
            _vld.raise_if(
                _os.path.isabs(self._path), ValueError,
                f'{self.__class__.__name__} expects a relative path when root has been set'
            )
            self._path = get_abs(self._path, base)

        self._head, self._tail = _os.path.split(self._path)
        self._end, self._ext = _os.path.splitext(self._tail)
예제 #5
0
def get_alphachars(text: str) -> str:
    """
    Returns all alphabetic characters [a-zA-Z] in string *text* in a new (concatenated) string.

    Example:

        >>> get_alphachars('Test123')
        'Test'

    :param text:    The string to search.
    """
    _vld.pass_if(_vld.is_text(text), TypeError,
                 "'text' attribute must be a string (got {!r})".format(text))
    return _const.CHAR_EMPTY.join(s for s in text if s.isalpha())
예제 #6
0
    def walk(node, level):
        if (((levels is not None) and (level > levels)) or _vld.is_text(node)
                or ((base_type is not None) and isinstance(node, base_type))):
            yield node
            return

        try:
            tree = iter(node)
        except TypeError:
            yield node
            return
        else:
            for child in tree:
                for v in walk(child, level + 1):
                    yield v
예제 #7
0
    def _parse(self, plan, user_prefix):
        """ Parses the plan, sets the plan parameters and validates them. """

        _vld.pass_if(_vld.is_text(plan, False), ValueError, "'plan' argument must be a string")

        parts = plan.upper().split(self.__PLAN_SEP)

        self._gpn = _tu.get_alphachars(parts[-1])
        self._num = _tu.get_digits(parts[-1])

        _vld.pass_if(self._gpn, ValueError, "'plan' argument must start with one or more characters (e.g. 'PW')")
        _vld.pass_if(self._num, ValueError, "'plan' argument must contain a number")

        if int(self._num) >= 1000:
            self._pfx = user_prefix + self.__PLAN_SEP
예제 #8
0
def get_digits(text: str) -> str:
    """
    Returns all numeric characters (digits) in string *text* in a new (concatenated) **string**.

    Example:

        >>> get_digits('Test123')
        '123'
        >>> int(get_digits('The answer is 42'))
        42

    :param text:    The string to search.
    """
    _vld.pass_if(_vld.is_text(text), TypeError,
                 "'text' attribute must be a string (got {!r})".format(text))
    return _const.CHAR_EMPTY.join(s for s in text if s.isdigit())
예제 #9
0
    def __init__(self, where_field, operator=None, *values):

        self._locked = False
        self._fields = {}
        self._parts = []
        if _vld.is_text(where_field, False) and operator:
            self._fields.setdefault(where_field.lower(), [0])
            self._parts.append(where_field)
            self._add_expression(operator, *values)
        elif isinstance(where_field, self.__class__):
            # When `where_field` is another Where instance, simply wrap its contents in parentheses
            self._update_fieldmap(where_field._fields, 1)
            self._parts = ['('] + where_field._parts + [')']
        elif where_field is not None:
            raise InitError(
                '{0} expects a field name and an operator, or another {0} instance'
                .format(Where.__name__))
예제 #10
0
파일: queries.py 프로젝트: geocom-gis/gpf
    def _check_types(*args):
        """ Checks that all query values have compatible data types. Applies to IN and BETWEEN operators. """

        # Check that none of the arguments are of type 'object' (this breaks the type check)
        _vld.raise_if(
            any(v.__class__ is object for v in args), ValueError,
            'Values of type object are not allowed in IN and BETWEEN queries')

        # Get the first value and get its type
        sample_val = args[0]
        sample_type = type(sample_val)

        # Allow for some flexibility concerning numbers and strings
        if _vld.is_number(sample_val, True):
            # For now, we will allow a mixture of floats and integers (and bools) in the list of values
            sample_type = int, float, bool
        elif _vld.is_text(sample_val):
            # Allow str and unicode (basestring type sometimes fails with isinstance)
            sample_type = str, unicode

        return all(isinstance(v, sample_type) for v in args)
예제 #11
0
def format_plural(word, number, plural_suffix='s'):
    """
    Function that prefixes `word` with `number` and appends `plural_suffix` to it if `number` <> 1.
    Note that this only works for words with simple conjugation (where the base word and suffix do not change).
    E.g. words like 'sheep' or 'life' will be falsely pluralized ('sheeps' and 'lifes' respectively).

    Examples:

        >>> format_plural('{} error', 42)
        '42 errors'

        >>> format_plural('{} bus', 99, 'es')
        '99 buses'

        >>> format_plural('{} goal', 1)
        '1 goal'

        >>> format_plural('{} regret', 0)
        '0 regrets'

    :param word:            The word that should be pluralized if `number` <> 1.
    :param number:          The numeric value for which `word` will be prefixed and pluralized.
    :param plural_suffix:   If `word` is a constant and the `plural_suffix` for it cannot be 's', set your own.
    :type word:             str, unicode
    :type number:           int, float
    :type plural_suffix:    str, unicode
    :rtype:                 str, unicode
    """
    # Argument validation
    _vld.pass_if(_vld.is_number(number), TypeError,
                 "'number' attribute must be numeric")
    _vld.pass_if(_vld.is_text(word, False), TypeError,
                 "'word' attribute must be a non-empty string")
    _vld.pass_if(word[-1].isalpha(), ValueError,
                 "'word' must end with an alphabetic character")

    if number == 1:
        plural_suffix = EMPTY_STR
    return type(word)(EMPTY_STR).join(
        (str(number), SPACE, word, plural_suffix))
예제 #12
0
    def _format_value(value):
        """
        Private method to format *value* for use in an SQL expression based on its type.
        This basically means that all non-numeric values will be quoted.
        If value is a :class:`gpf.common.guids.Guid` string, the result will be wrapped in curly braces and quoted.

        :param value:   Any value. Single quotes in strings will be escaped automatically.
        :return:        A formatted string.
        :rtype:         str, unicode
        """
        if _vld.is_number(value, True):
            # Note: a `bool` is of instance `int` but calling format() on it will return a string (True or False)
            # To prevent this from happening, we'll use the `real` numeric value instead (on int, float and bool)
            return format(value.real)
        elif _vld.is_text(value):
            try:
                return repr(str(_guids.Guid(value)))
            except (_guids.Guid.MissingGuidError, _guids.Guid.BadGuidError):
                return _tu.to_repr(value)
        raise TypeError(
            'All values in an SQL expression must be of type str, bool, int or float'
        )
예제 #13
0
    def _fix_values(self, *values, **kwargs):
        """
        Private method to validate *values* for use in an SQL expression.
        All values, regardless if they are iterables themselves, will be flattened (up to 1 level).
        If the values do not have comparable types (i.e. all numeric, all strings), a ``TypeError`` will be raised.

        :param values:          An iterable (of iterables) with values to use for the SQL expression.
        :keyword check_only:    When False (default=True), values will be sorted and duplicates will be removed.
                                Furthermore, the returned values will be formatted for the SQL expression.
                                When True, the values will only be flattened and checked for comparable types.
        :return:                A generator of checked (and formatted) values.
        """
        _vld.pass_if(
            values, OperatorError,
            'Specified {} operator requires at least one value'.format(
                Where.__name__))

        values = [v for v in _iter.collapse(values, levels=1)]
        unique_values = frozenset(values)
        first_val = _iter.first(unique_values)

        if _vld.is_number(first_val, True):
            # For now, allow a mixture of floats and integers (and bools) in the list of values
            # TODO: When input field is an arcpy.Field instance, filter by field.type
            first_type = (int, float, bool)
        elif _vld.is_text(first_val):
            first_type = (str, unicode)
        else:
            first_type = type(first_val)

        _vld.raise_if(
            any(not isinstance(v, first_type) for v in unique_values),
            TypeError, 'All {} values must have the same data type'.format(
                Where.__name__))

        check_only = kwargs.get(_CHECK_ARG, False)
        return (v if check_only else self._format_value(v)
                for v in (values if check_only else sorted(unique_values)))
예제 #14
0
파일: queries.py 프로젝트: geocom-gis/gpf
    def _format_value(self, value):
        """
        Private method to format *value* for use in an SQL expression based on its type.
        This basically means that all non-numeric values (strings) will be quoted.
        If value is a :class:`gpf.common.guids.Guid` instance, the result will be wrapped in curly braces and quoted.

        :param value:   Any value. Single quotes in strings will be escaped automatically.
        :return:        A formatted string.
        :rtype:         unicode
        """
        if _vld.is_number(value, True):
            # Note: a `bool` is of instance `int` but calling format() on it will return a string (True or False).
            # To prevent this from happening, we'll use the `real` numeric part instead (on int, float and bool).
            return _tu.to_unicode(value.real, self._enc)

        if isinstance(value, _guids.Guid):
            # Parse Guid instances as strings
            value = str(value)
        if _vld.is_text(value):
            return _tu.to_unicode(_tu.to_repr(value, self._enc), self._enc)

        raise ValueError(
            'All values in an SQL expression must be text strings or numeric values'
        )
예제 #15
0
 def func_wrapper(self, *args):
     args = (x.upper() if _vld.is_text(x) else x for x in args)
     return func[-1](self, *args)