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
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))
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
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
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
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
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
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
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
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)
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")
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
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)
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
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))
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))
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