Esempio n. 1
0
    def __new__(cls, *args, **kwargs):
        if kwargs:
            assert not args
            return type(cls.__name__, (cls, ), kwargs)

        assert len(args) == 1
        value = super().__new__(cls, *args)

        if cls.trim_whitespace:
            value = value.strip()

        if cls.min_length is not None:
            if len(value) < cls.min_length:
                if cls.min_length == 1:
                    raise SchemaError(error_message(cls, 'blank'))
                else:
                    raise SchemaError(error_message(cls, 'min_length'))

        if cls.max_length is not None:
            if len(value) > cls.max_length:
                raise SchemaError(error_message(cls, 'max_length'))

        if cls.pattern is not None:
            if not re.search(cls.pattern, value):
                raise SchemaError(error_message(cls, 'pattern'))

        return value
Esempio n. 2
0
    def __new__(cls, *args, **kwargs):
        if kwargs:
            assert not args
            return type(cls.__name__, (cls, ), kwargs)

        assert len(args) == 1
        value = args[0]

        if value not in cls.enum:
            if len(cls.enum) == 1:
                raise SchemaError(error_message(cls, 'exact'))
            raise SchemaError(error_message(cls, 'enum'))
        return value
Esempio n. 3
0
    def __new__(cls, *args, **kwargs):
        assert len(args) == 1 and not kwargs
        value = args[0]
        try:
            value = cls.native_type.__new__(cls, value)
        except (TypeError, ValueError):
            raise SchemaError(cls, 'type')

        if cls.minimum is not None:
            if cls.exclusive_minimum:
                if value <= cls.minimum:
                    raise SchemaError(cls, 'exclusive_minimum')
            else:
                if value < cls.minimum:
                    raise SchemaError(cls, 'minimum')

        if cls.maximum is not None:
            if cls.exclusive_maximum:
                if value >= cls.maximum:
                    raise SchemaError(cls, 'exclusive_maximum')
            else:
                if value > cls.maximum:
                    raise SchemaError(cls, 'maximum')

        if cls.multiple_of is not None:
            if isinstance(cls.multiple_of, float):
                failed = not (value * (1 / cls.multiple_of)).is_integer()
            else:
                failed = value % cls.multiple_of
            if failed:
                raise SchemaError(cls, 'multiple_of')

        return value
Esempio n. 4
0
    def __init__(self, value):
        try:
            value = dict(value)
        except TypeError:
            raise SchemaError(error_message(self, 'type'))

        # Ensure all property keys are strings.
        errors = {}
        if any(not isinstance(key, str) for key in value.keys()):
            raise SchemaError(error_message(self, 'invalid_key'))

        # Enforce any required properties.
        if self.required is not None:
            for key in self.required:
                if key not in value:
                    errors[key] = error_message(self, 'required')

        # Properties
        if self.properties is not None:
            for key, child_schema in self.properties.items():
                try:
                    item = value.pop(key)
                except KeyError:
                    if hasattr(child_schema, 'default'):
                        # If a key is missing but has a default, then use that.
                        self[key] = child_schema.default
                else:
                    # Coerce value into the given schema type if needed.
                    if isinstance(item, child_schema):
                        self[key] = item
                    else:
                        try:
                            self[key] = child_schema(item)
                        except SchemaError as exc:
                            errors[key] = exc.detail

        if errors:
            raise SchemaError(errors)
Esempio n. 5
0
    def __new__(cls, *args, **kwargs):
        assert len(args) == 1 and not kwargs
        value = str.__new__(cls, *args)

        if cls.trim_whitespace:
            value = value.strip()

        if cls.min_length is not None:
            if len(value) < cls.min_length:
                if cls.min_length == 1:
                    raise SchemaError(cls, 'blank')
                else:
                    raise SchemaError(cls, 'min_length')

        if cls.max_length is not None:
            if len(value) > cls.max_length:
                raise SchemaError(cls, 'max_length')

        if cls.pattern is not None:
            if not re.search(cls.pattern, value):
                raise SchemaError(cls, 'pattern')

        return value
Esempio n. 6
0
    def __new__(self, *args, **kwargs):
        assert len(args) == 1 and not kwargs
        value = args[0]

        if isinstance(value, str):
            try:
                return {
                    'true': True,
                    'false': False,
                    '1': True,
                    '0': False
                }[value.lower()]
            except KeyError:
                raise SchemaError(self, 'type')
        return bool(value)
Esempio n. 7
0
    def __new__(cls, *args, **kwargs):
        if kwargs:
            assert not args
            return type(cls.__name__, (cls, ), kwargs)

        assert len(args) == 1
        value = args[0]

        if isinstance(value, str):
            try:
                return {
                    'true': True,
                    'false': False,
                    '1': True,
                    '0': False
                }[value.lower()]
            except KeyError:
                raise SchemaError(error_message(cls, 'type'))
        return bool(value)
Esempio n. 8
0
    def __init__(self, value):
        try:
            value = list(value)
        except TypeError:
            raise SchemaError(error_message(self, 'type'))

        if isinstance(self.items, list) and len(self.items) > 1:
            if len(value) < len(self.items):
                raise SchemaError(error_message(self, 'min_items'))
            elif len(value) > len(self.items) and not self.additional_items:
                raise SchemaError(error_message(self, 'max_items'))

        if len(value) < self.min_items:
            raise SchemaError(error_message(self, 'min_items'))
        elif self.max_items is not None and len(value) > self.max_items:
            raise SchemaError(error_message(self, 'max_items'))

        # Ensure all items are of the right type.
        errors = {}
        if self.unique_items:
            seen_items = set()

        for pos, item in enumerate(value):
            try:
                if isinstance(self.items, list):
                    if pos < len(self.items):
                        item = self.items[pos](item)
                elif self.items is not None:
                    item = self.items(item)

                if self.unique_items:
                    if item in seen_items:
                        raise SchemaError(error_message(self, 'unique_items'))
                    else:
                        seen_items.add(item)

                self.append(item)
            except SchemaError as exc:
                errors[pos] = exc.detail

        if errors:
            raise SchemaError(errors)
Esempio n. 9
0
    def __new__(cls, *args, **kwargs):
        if kwargs:
            assert not args
            return type(cls.__name__, (cls, ), kwargs)

        assert len(args) == 1
        value = args[0]
        try:
            value = cls._numeric_type.__new__(cls, value)
        except (TypeError, ValueError):
            raise SchemaError(cls, 'type')

        if cls.minimum is not None:
            if cls.exclusive_minimum:
                if value <= cls.minimum:
                    raise SchemaError(cls, 'exclusive_minimum')
            else:
                if value < cls.minimum:
                    raise SchemaError(cls, 'minimum')

        if cls.maximum is not None:
            if cls.exclusive_maximum:
                if value >= cls.maximum:
                    raise SchemaError(cls, 'exclusive_maximum')
            else:
                if value > cls.maximum:
                    raise SchemaError(cls, 'maximum')

        if cls.multiple_of is not None:
            if isinstance(cls.multiple_of, float):
                failed = not (float(value) / cls.multiple_of).is_integer()
            else:
                failed = value % cls.multiple_of
            if failed:
                raise SchemaError(cls, 'multiple_of')

        return value
Esempio n. 10
0
    def __init__(self, value):
        value = dict(value)

        # Ensure all property keys are strings.
        errors = {}
        if any(not isinstance(key, str) for key in value.keys()):
            errors[''] = self.errors['invalid_key']

        # Enforce any required properties.
        if self.required is not None:
            for key in self.required:
                if key not in value:
                    errors[key] = self.errors['required']

        # Ensure object has at least 'min_properties'
        if self.min_properties is not None:
            if len(value) < self.min_properties:
                if self.min_properties == 1:
                    errors[''] = self.errors('empty')
                else:
                    errors[''] = self.errors['min_properties'].format(
                        min_properties=self.min_properties)

        # Ensure object has at no more than 'max_properties'
        if self.max_properties is not None:
            if len(value) > self.max_properties:
                errors[''] = self.errors['max_properties'].format(
                    max_properties=self.max_properties)

        # Properties
        if self.properties is not None:
            for key, child_schema in self.properties.items():
                try:
                    item = value.pop(key)
                except KeyError:
                    if hasattr(child_schema, 'default'):
                        # If a key is missing but has a default, then use that.
                        self[key] = child_schema.default
                else:
                    # Coerce value into the given schema type if needed.
                    if isinstance(item, child_schema):
                        self[key] = item
                    else:
                        self[key] = child_schema(item)

        # Pattern properties
        if self.pattern_properties is not None:
            for pattern, child_schema in self.pattern_properties.items():
                for key in list(value.keys()):
                    if re.search(pattern, key):
                        # Set the value, coerceing into the required schema if needed.
                        item = value.pop(key)
                        if isinstance(item, child_schema):
                            self[key] = item
                        else:
                            self[key] = child_schema(item)

        # Additional properties
        if self.additional_properties is not None:
            if self.additional_properties is True:
                # Allow additional properties
                for key, item in value.items():
                    self[key] = item
            elif self.additional_properties is False:
                # Disallow additional properties
                for key in value.keys():
                    errors[key] = self.errors['invalid_property']
            elif isinstance(self.additional_properties, type):
                # Allow additional properties, enforcing a schema
                child_schema = self.additional_properties
                for key, item in value.items():
                    if isinstance(item, child_schema):
                        self[key] = item
                    else:
                        self[key] = child_schema(item)

        if errors:
            raise SchemaError(errors)