Пример #1
0
    def process(self, name, value):
        """
        :type self: TypedClassBaseField
        :type name: str
        :type value: TypedClassAny
        :rtype: TypedClassAny
        """
        if self.required is False and value is None:
            return

        if self.desimplifier is not None:
            try:
                value = self.desimplifier(value)
            except TypedClassValidationError as exc:
                raise TypedClassValidationError('{name}: {error}'.format(
                    name=name,
                    error=str(exc),
                ))

        for func in self.all_validators:
            try:
                func(self, value)
            except TypedClassValidationError as exc:
                raise TypedClassValidationError('{name}: {error}'.format(
                    name=name,
                    error=str(exc),
                ))

        return value
Пример #2
0
    def process(self, name, value):
        """
        :type self: TypedClassBaseField
        :type name: str
        :type value: TypedClassAny
        :rtype: tuple|None
        """
        from typedclass.core import TypedClass
        # <-- circular import

        if self.required is False and value is None:
            return

        if isinstance(value, (tuple, list)):
            converted_value = []
            for idx, entry in enumerate(value):
                try:
                    if isinstance(entry, self.cls):
                        converted_value.append(entry)
                    elif isinstance(entry, dict) and issubclass(
                            self.cls, TypedClass):
                        f_instance = self.cls(**entry)
                        converted_value.append(f_instance)
                    elif issubclass(self.cls, BaseDataField):
                        f_instance = self.cls()
                        _converted = f_instance.process(
                            name='{name}[{idx}]'.format(
                                name=name,
                                idx=idx,
                            ),
                            value=entry,
                        )
                        converted_value.append(_converted)
                    else:
                        raise TypedClassValidationError()
                except TypedClassValidationError:
                    raise TypedClassValidationError(
                        '{name}: element with idx {idx} is not instance of {cls}'
                        .format(
                            name=name,
                            idx=idx,
                            cls=self.cls,
                        ))
            return tuple(converted_value)
        else:
            raise TypedClassValidationError(
                '{name} is not list or tuple of {cls}'.format(
                    name=name,
                    cls=self.cls,
                ))
Пример #3
0
def validator_float(field, value):
    """
    :type field: TypedClassBaseDataField
    :rtype: None
    """
    if not isinstance(value, float):
        raise TypedClassValidationError('Not an float')

    if field.min_value is not None and value < field.min_value:
        raise TypedClassValidationError('Float value < {}'.format(
            field.min_value))

    if field.max_value is not None and value > field.max_value:
        raise TypedClassValidationError('Float value > {}'.format(
            field.max_value))
Пример #4
0
def desimplifier_datetime(value):
    """
    :type value: TypedClassAny
    :rtype: TypedClassDatetime|TypedClassAny
    """
    if isinstance(value, str):
        try:
            return dt.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S:%f')
        except ValueError:
            pass

        # ATTENTION!
        # all formats below are deprecated!
        # in future versions of typedclass this code will be deleted!
        # TODO: deprecated, remove after implementing custom format in f.DateTime
        try:
            return dt.datetime.strptime(value, '%Y-%m-%dT%H:%M:%SZ')
        except ValueError:
            pass

        try:
            return dt.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S')
        except ValueError:
            pass

        try:
            return dt.datetime.strptime(value, '%Y-%m-%dT%H:%M')
        except ValueError:
            raise TypedClassValidationError('Not a datetime')

    return value
Пример #5
0
def validator_binary(field, value):
    """
    :type field: TypedClassBaseDataField
    :rtype: None
    """
    if not isinstance(value, bytes):
        raise TypedClassValidationError('Not a binary')
Пример #6
0
def validator_decimal(field, value):
    """
    :type field: TypedClassBaseDataField
    :type value: TypedClassAny
    :rtype: None
    """
    if not isinstance(value, Decimal):
        raise TypedClassValidationError('Not a Decimal')

    if field.min_value is not None and value < field.min_value:
        raise TypedClassValidationError('Decimal value < {}'.format(
            field.min_value))

    if field.max_value is not None and value > field.max_value:
        raise TypedClassValidationError('Decimal value > {}'.format(
            field.max_value))
Пример #7
0
    def process(self, name, value):
        """
        :type self: TypedClassBaseField
        :type name: str
        :type value: TypedClassAny
        :rtype: set|None
        """
        from typedclass.core import TypedClass
        # <-- circular import

        if self.required is False and value is None:
            return

        if isinstance(value, (set, frozenset, tuple, list)):
            converted_value = set()
            for entry in value:
                try:
                    if isinstance(entry, self.cls):
                        converted_value.add(entry)
                    elif isinstance(entry, dict) and issubclass(self.cls, TypedClass):
                        f_instance = self.cls(**entry)
                        converted_value.add(f_instance)
                    elif issubclass(self.cls, BaseDataField):
                        f_instance = self.cls()
                        _converted = f_instance.process(
                            name=name,
                            value=entry,
                        )
                        converted_value.add(_converted)
                    else:
                        raise TypedClassValidationError()
                except TypedClassValidationError:
                    raise TypedClassValidationError(
                        '{name}: element "{value}" is not instance of {cls}'.format(
                            name=name,
                            value=entry,
                            cls=self.cls,
                        )
                    )
            return converted_value
        else:
            raise TypedClassValidationError(
                '{name} is not set / frozenset / list / tuple of {cls}'.format(
                    name=name,
                    cls=self.cls,
                )
            )
Пример #8
0
def simplifier_time(value):
    """
    :type value: TypedClassAny
    :rtype: str
    """
    if isinstance(value, dt.time):
        return value.strftime('%H:%M:%S')

    raise TypedClassValidationError('Not a time')
Пример #9
0
def validator_int(field, value):
    """
    :type field: TypedClassBaseDataField
    :rtype: None
    """
    if not isinstance(value, int):
        raise TypedClassValidationError('Not an int')

    if field.min_value is not None and value < field.min_value:
        raise TypedClassValidationError('Int value < {}'.format(
            field.min_value))

    if field.max_value is not None and value > field.max_value:
        raise TypedClassValidationError('Int value > {}'.format(
            field.max_value))

    if field.choices and value not in field.choices:
        raise TypedClassValidationError('value not found in choices')
Пример #10
0
def simplifier_decimal(value):
    """
    :type value: TypedClassAny
    :rtype: str
    """
    if isinstance(value, Decimal):
        return str(value)

    raise TypedClassValidationError('Not a Decimal')
Пример #11
0
def validator_string(field, value):
    """
    :type field: TypedClassBaseDataField
    :rtype: None
    """
    if not isinstance(value, str):
        raise TypedClassValidationError('Not a string')

    if field.min_length and len(value) < field.min_length:
        raise TypedClassValidationError('String length < {}'.format(
            field.min_length))

    if field.max_length and len(value) > field.max_length:
        raise TypedClassValidationError('String length > {}'.format(
            field.max_length))

    if field.choices and value not in field.choices:
        raise TypedClassValidationError('value not found in choices')
Пример #12
0
def simplifier_datetime(value):
    """
    :type value: TypedClassAny
    :rtype: str
    """
    if isinstance(value, dt.datetime):
        return value.strftime('%Y-%m-%dT%H:%M:%S:%f')

    raise TypedClassValidationError('Not a datetime')
Пример #13
0
def validator_string_english(field, value):
    """
    :type field: TypedClassBaseDataField
    :rtype: None
    """
    error_msg = 'Not a string english'

    if not isinstance(value, str):
        raise TypedClassValidationError(error_msg)

    # ATTENTION!
    # don't forget about spaces!
    allowed_chars = string.ascii_letters + string.digits + "!#$%\()*+,-./:;&=?@[\\]^_`{|}~ "

    for character in value:
        if character not in allowed_chars:
            raise TypedClassValidationError(error_msg)

    return
Пример #14
0
def validator_time(field, value):
    """
    :type field: TypedClassBaseDataField
    :type value: TypedClassAny
    :rtype: None
    """
    if isinstance(value, dt.time):
        return

    raise TypedClassValidationError('Not a time')
Пример #15
0
 def loads(cls, data, serializer=SimpleSerializer):
     """
     :type cls: TypedClassCls
     :type data: str|TypedClassBytes
     :type serializer: TypedClassBaseSerializerCls
     :rtype: TypedClass
     """
     try:
         return serializer.loads(cls, data)
     except ValueError:
         raise TypedClassValidationError('load data error')
Пример #16
0
def desimplifier_date(value):
    """
    :type value: TypedClassAny
    :rtype: TypedClassDate|TypedClassAny
    """
    if isinstance(value, str):
        try:
            return dt.datetime.strptime(value, '%Y-%m-%d').date()
        except ValueError:
            raise TypedClassValidationError('Not a date')

    return value
Пример #17
0
def desimplifier_float(value):
    """
    :type value: TypedClassAny
    :rtype: float|TypedClassAny
    """
    if isinstance(value, (str, int)):
        try:
            return float(value)
        except ValueError:
            raise TypedClassValidationError('Not a Float')

    return value
Пример #18
0
def validator_string_int(field, value):
    """
    :type field: TypedClassBaseDataField
    :rtype: None
    """
    if isinstance(value, (
            str,
            int,
    )):
        return

    raise TypedClassValidationError('Not a string / int')
Пример #19
0
def desimplifier_decimal(value):
    """
    :type value: TypedClassAny
    :rtype: TypedClassDecimal|TypedClassAny
    """
    if isinstance(value, (str, int)):
        try:
            return Decimal(value)
        except DecimalException:
            raise TypedClassValidationError('Not a Decimal')

    return value
Пример #20
0
    def process_base(self, name, value):
        """
        base validation for all fields

        value - external raw_data

        :type self: TypedClassBaseField
        :type name: str
        :type value: TypedClassAny
        :rtype: None
        """
        if self.required is True and value is None:
            raise TypedClassValidationError('value "{}" is required but None'.format(name))
Пример #21
0
def validator_string_email(field, value):
    """
    :type field: TypedClassBaseDataField
    :rtype: None
    """
    error_msg = 'Not a string email'

    if not isinstance(value, str):
        raise TypedClassValidationError(error_msg)

    if not len(value) < 255:
        raise TypedClassValidationError(error_msg)

    if value.count('@') > 1:
        raise TypedClassValidationError(error_msg)

    if '..' in value:
        raise TypedClassValidationError(error_msg)

    if re.search(_EMAIL_RE, value, re.I):
        return

    raise TypedClassValidationError(error_msg)
Пример #22
0
    def process(self, name, value):
        """
        :type self: TypedClassBaseField
        :type name: str
        :type value: TypedClassAny
        :rtype: dict|None
        """
        if self.required is False and value is None:
            return

        if not isinstance(value, Mapping):
            raise TypedClassValidationError(
                '{} is not Mapping type'.format(name)
            )

        return value
Пример #23
0
def desimplifier_time(value):
    """
    :type value: TypedClassAny
    :rtype: TypedClassTime|TypedClassAny
    """
    if isinstance(value, str):
        try:
            return dt.datetime.strptime(value, '%H:%M:%S').time()
        except ValueError:
            pass

        try:
            return dt.datetime.strptime(value, '%H:%M').time()
        except ValueError:
            raise TypedClassValidationError('Not a time')

    return value
Пример #24
0
def test_desimplifier_error():
    # create our new class, because we'll change it behaviour
    class TestBool(f.Bool):
        pass

    m_desimplifier = Mock(side_effect=TypedClassValidationError('test'))
    TestBool.desimplifier = m_desimplifier
    f_bool = TestBool()
    v_bool = '1'

    error = None
    try:
        f_bool.process(name='f_bool', value=v_bool)
    except TypedClassValidationError as exc:
        error = exc

    assert error
    msg = str(error)
    assert msg == 'f_bool: test'
Пример #25
0
    def process(self, name, value):
        """
        :type self: TypedClassBaseField
        :type name: str
        :type value: TypedClassAny
        :rtype: TypedClass|None
        """
        if self.required is False and value is None:
            return

        if isinstance(value, self.cls):
            return value
        elif isinstance(value, dict):
            f_instance = self.cls(**value)
            return f_instance
        else:
            raise TypedClassValidationError(
                '{name} is not instance of {cls}'.format(
                    name=name,
                    cls=self.cls,
                ))
Пример #26
0
    def process(self, name, value):
        """
        :type self: TypedClassBaseField
        :type name: str
        :type value: TypedClassAny
        :rtype: dict|None
        """
        if self.required is False and value is None:
            return

        if not isinstance(value, Mapping):
            raise TypedClassValidationError(
                '{} is not Mapping type'.format(name))

        converted = {}
        for _key, _value in value.items():
            _key_converted = self.key.process('key', _key)
            _value_converted = self.value.process('value of {}'.format(_key),
                                                  _value)
            converted[_key_converted] = _value_converted

        return converted
Пример #27
0
 def _positive_validator(field, value):
     if value < pyDecimal('0'):
         raise TypedClassValidationError('Decimal is negative')
Пример #28
0
 def _future_validator(field, value):
     if value < dt.date.today():
         raise TypedClassValidationError('Date is not in future')
Пример #29
0
 def _morning_validator(field, value):
     # 06:00 <= time < 12:00
     if not (dt.time(6, 0) <= value < dt.time(12, 0)):
         raise TypedClassValidationError('Time is not in the morning range')
Пример #30
0
 def _true_validator(field, value):
     if value is False:
         raise TypedClassValidationError('Bool is not True')