Exemple #1
0
    def validated_value(self, value):
        assert value

        translated_value = ""
        found_decimal_separator = False
        for character_to_process in value:
            if character_to_process == self.decimal_separator:
                if found_decimal_separator:
                    raise errors.FieldValueError(
                        _("decimal field must contain only one decimal separator (%s): %s")
                        % (_compat.text_repr(self.decimal_separator), _compat.text_repr(value)))
                translated_value += "."
                found_decimal_separator = True
            elif self.thousands_separator and (character_to_process == self.thousands_separator):
                if found_decimal_separator:
                    raise errors.FieldValueError(_(
                        "decimal field must contain thousands separator (%r) only before "
                        "decimal separator (%r): %r "
                        ) % (self.thousands_separator, self.decimal_separator, value))
            else:
                translated_value += character_to_process

        try:
            result = decimal.Decimal(translated_value)
        except Exception as error:
            # TODO: limit exception handler to decimal exception or whatever decimal.Decimal raises.
            message = "value is %r but must be a decimal number: %s" % (value, error)
            raise errors.FieldValueError(message)

        try:
            self.valid_range.validate(self._field_name, result)
        except errors.RangeValueError as error:
            raise errors.FieldValueError(str(error))

        return result
Exemple #2
0
    def validate_length(self, value):
        """
        Validate that ``value`` conforms to
        :py:attr:`~cutplace.fields.AbstractFieldFormat.length`.

        :raises cutplace.errors.FieldValueError: if ``value`` is too short \
          or too long
        """
        assert value is not None

        if self.length is not None and not (self.is_allowed_to_be_empty and
                                            (value == '')):
            try:
                if self.data_format.format == data.FORMAT_FIXED:
                    # Length of fixed format is considered a maximum, fewer characters have to be padded later.
                    value_length = len(value)
                    fixed_length = self.length.lower_limit
                    if value_length > fixed_length:
                        raise errors.FieldValueError(
                            'fixed format field must have at most %d characters instead of %d: %s'
                            % (fixed_length, value_length,
                               _compat.text_repr(value)))
                else:
                    self.length.validate(
                        "length of '%s' with value %s" %
                        (self.field_name, _compat.text_repr(value)),
                        len(value))
            except errors.RangeValueError as error:
                raise errors.FieldValueError(six.text_type(error))
Exemple #3
0
    def validated_value(self, value):
        assert value

        try:
            value_as_int = int(value)
        except ValueError:
            raise errors.FieldValueError("value must be an integer number: %s" % _compat.text_repr(value))
        try:
            self.valid_range.validate("value", value_as_int)
        except errors.RangeValueError as error:
            raise errors.FieldValueError(six.text_type(error))
        return value_as_int
Exemple #4
0
    def validated_value(self, value):
        assert value

        if not self.regex.match(value):
            raise errors.FieldValueError(
                'value %r must match pattern: %r (regex %r)' % (value, self.rule, self.pattern))
        return value
Exemple #5
0
    def validated_value(self, value):
        assert value

        if not self.regex.match(value):
            raise errors.FieldValueError(
                _('value %s must match pattern: %s (regex %s)')
                % (_compat.text_repr(value), _compat.text_repr(self.rule), _compat.text_repr(self.pattern)))
        return value
Exemple #6
0
    def validated_value(self, value):
        assert value

        if value not in self.choices:
            raise errors.FieldValueError(
                "value is %s but must be one of: %s"
                % (_compat.text_repr(value), _tools.human_readable_list(self.choices)))
        return value
Exemple #7
0
    def validated_value(self, value):
        assert value

        if not self.regex.match(value):
            raise errors.FieldValueError(
                "value %s must match regular expression: %s" %
                (_compat.text_repr(value), _compat.text_repr(self.rule)))
        return value
Exemple #8
0
    def validated_value(self, value):
        assert value

        if value != self._constant:
            raise errors.FieldValueError(
                "value is %s but must be constant: %s" %
                (_compat.text_repr(value), _compat.text_repr(self._constant)))
        return value
Exemple #9
0
    def validated_value(self, value):
        assert value

        try:
            result = time.strptime(value, self.strptimeFormat)
        except ValueError:
            raise errors.FieldValueError(
                "date must match format %s (%s) but is: %r (%s)"
                % (self.human_readable_format, self.strptimeFormat, value, sys.exc_info()[1]))
        return result
Exemple #10
0
    def validate_row(self, row):
        """
        Validate a single ``row``:

        1. Check if the number of items in ``row`` matches the number of
           fields in the CID
        2. Check that all fields conform to their field format (as defined
           by :py:class:`cutplace.fields.AbstractFieldFormat` and its
           descendants)
        3. Check that the row conforms to all row checks (as defined by
           :py:meth:`cutplace.checks.AbstractCheck.check_row`)

        The caller is responsible for :py:attr:`~.location` pointing to the
        correct row in the data while ``validate_row`` takes care of calling
        :py:meth:`cutplace.errors.Location.set_cell` appropriately.
        """
        assert row is not None
        assert self.location is not None

        # Validate that number of fields.
        actual_item_count = len(row)
        if actual_item_count < self._expected_item_count:
            raise errors.DataError(
                'row must contain %d fields but only has %d: %s' %
                (self._expected_item_count, actual_item_count, row),
                self.location)
        if actual_item_count > self._expected_item_count:
            raise errors.DataError(
                'row must contain %d fields but has %d, additional values are: %s'
                % (self._expected_item_count, actual_item_count,
                   row[self._expected_item_count:]), self.location)

        # Validate each field according to its format.
        for field_index, field_value in enumerate(row):
            self.location.set_cell(field_index)
            field_to_validate = self.cid.field_formats[field_index]
            try:
                if not isinstance(field_value, six.text_type):
                    raise errors.FieldValueError(
                        'type must be %s instead of %s: %s' %
                        (six.text_type.__name__, type(field_value).__name__,
                         _compat.text_repr(field_value)))
                field_to_validate.validated(field_value)
            except errors.FieldValueError as error:
                error.prepend_message(
                    'cannot accept field %s' %
                    _compat.text_repr(field_to_validate.field_name),
                    self.location)
                raise

        # Validate the whole row according to row checks.
        self.location.set_cell(0)
        field_map = _create_field_map(self.cid.field_names, row)
        for check_name in self.cid.check_names:
            self.cid.check_map[check_name].check_row(field_map, self.location)
Exemple #11
0
    def validate_empty(self, value):
        """
        Validate that ``value`` actually is not empty in case
        :py:attr:`~cutplace.fields.AbstractFieldFormat.is_allowed_to_be_empty`
        is ``True``.

        :raises cutplace.errors.FieldValueError: if ``value`` is empty but \
          must not be
        """
        if not self.is_allowed_to_be_empty:
            if not value:
                raise errors.FieldValueError("value must not be empty")
Exemple #12
0
 def validated_value(self, color_name):
     assert color_name
     if color_name == "red":
         result = (1.0, 0.0, 0.0)
     elif color_name == "green":
         result = (0.0, 1.0, 0.0)
     elif color_name == "blue":
         result = (0.0, 1.0, 0.0)
     else:
         raise errors.FieldValueError(
             "color name is %r but must be one of: red, green, blue" %
             color_name)
     return result
Exemple #13
0
    def __init__(self, field_name, is_allowed_to_be_empty, length_text, rule, data_format, empty_value=None):
        super(IntegerFieldFormat, self).__init__(field_name, is_allowed_to_be_empty, length_text, rule, data_format,
                                                 empty_value)
        # The default range is 32 bit. If the user wants a bigger range, he
        # has to specify it. Python's ``int`` scales to any range as long
        # there is enough memory available to represent it.
        has_length = (length_text is not None) and (length_text.strip() != '')
        has_rule = (rule is not None) and (rule.strip() != '')

        if has_length:
            length = self._length
            if data_format.format == data.FORMAT_FIXED and self._length.lower_limit == self._length.upper_limit:
                length = ranges.Range('1...%d' % self._length.upper_limit)

            length_range = ranges.create_range_from_length(length)

            if length_range.lower_limit == 1:
                self._is_allowed_to_be_empty = False

            if has_rule:
                rule_range = ranges.Range(rule)

                if length_range.upper_limit is not None and rule_range.upper_limit is not None \
                        and length_range.upper_limit < rule_range.upper_limit:
                    raise errors.FieldValueError('length upper limit must be greater than the rule upper limit')

                if length_range.lower_limit is not None and rule_range.lower_limit is not None \
                        and length_range.lower_limit > rule_range.lower_limit:
                    raise errors.FieldValueError('rule lower limit must be less than the length lower limit')

                self.valid_range = rule_range
            else:
                self.valid_range = length_range
        else:
            if has_rule:
                self.valid_range = ranges.Range(rule)
            else:
                self.valid_range = ranges.Range(ranges.DEFAULT_INTEGER_RANGE_TEXT)
Exemple #14
0
    def validated_value(self, value):
        assert value

        if not self._has_time and (self.data_format.format == data.FORMAT_EXCEL) and (value.endswith(DateTimeFieldFormat._NO_EXCEL_TIME)):
            value_to_validate = value[:-DateTimeFieldFormat._NO_EXCEL_TIME_LENGTH]
        else:
            value_to_validate = value

        try:
            result = time.strptime(value_to_validate, self.strptime_format)
        except ValueError:
            raise errors.FieldValueError(
                _("date must match format %s (%s) but is: %s (%s)")
                % (self.human_readable_format, self.strptime_format, _compat.text_repr(value_to_validate), sys.exc_info()[1]))
        return result
Exemple #15
0
    def validate_characters(self, value):
        """
        Validate that all characters in ``value`` are within
        :py:attr:`~cutplace.data.DataFormat.allowed_characters`.

        :raises cutplace.errors.FieldValueError: if any character in \
          ``value`` is not allowed
        """
        valid_character_range = self.data_format.allowed_characters
        if valid_character_range is not None:
            for character in value:
                try:
                    valid_character_range.validate("character", ord(character))
                except errors.RangeValueError as error:
                    raise errors.FieldValueError(
                        "value for fields '%s' must contain only valid characters: %s" % (self.field_name, error))
Exemple #16
0
    def validate_characters(self, value):
        """
        Validate that all characters in ``value`` are within
        :py:attr:`~cutplace.data.DataFormat.allowed_characters`.

        :raises cutplace.errors.FieldValueError: if any character in \
          ``value`` is not allowed
        """
        valid_character_range = self.data_format.allowed_characters
        if valid_character_range is not None:
            for character_column, character in enumerate(value, 1):
                character_code = ord(character)
                try:
                    valid_character_range.validate("character", character_code)
                except errors.RangeValueError:
                    raise errors.FieldValueError(_(
                        "character %s (code point U+%04x, decimal %d) in field '%s' at column %d must be an allowed "
                        "character: %s") % (
                            _compat.text_repr(character), character_code, character_code, self.field_name,
                            character_column, valid_character_range))
Exemple #17
0
    def validated_value(self, value):
        assert value

        if not self.regex.match(value):
            raise errors.FieldValueError("value %r must match regular expression: %r" % (value, self.rule))
        return value