예제 #1
0
    def errors(self, value):  # type: (AnyType) -> ListType[Error]
        if not isinstance(value, dict):
            return [Error('Not a dict')]

        result = []

        if self.max_length is not None and len(value) > self.max_length:
            result.append(
                Error('Dict contains more than {} value(s)'.format(
                    self.max_length)))
        elif self.min_length is not None and len(value) < self.min_length:
            result.append(
                Error('Dict contains fewer than {} value(s)'.format(
                    self.min_length)))

        for key, field in value.items():
            result.extend(
                update_error_pointer(error, key)
                for error in (self.key_type.errors(key) or []))
            result.extend(
                update_error_pointer(error, key)
                for error in (self.value_type.errors(field) or []))

        if not result and self.additional_validator:
            return self.additional_validator.errors(value)

        return result
예제 #2
0
    def errors(self, value):  # type: (AnyType) -> ListType[Error]
        if not isinstance(value, dict):
            return [Error('Not a dict')]

        result = []
        for key, field in self.contents.items():
            # Check key is present
            if key not in value:
                if key not in self.optional_keys:
                    result.append(
                        Error('Missing key: {}'.format(key),
                              code=ERROR_CODE_MISSING,
                              pointer=six.text_type(key)), )
            else:
                # Check key type
                result.extend(
                    update_error_pointer(error, key)
                    for error in (field.errors(value[key]) or []))
        # Check for extra keys
        extra_keys = set(value.keys()) - set(self.contents.keys())
        if extra_keys and not self.allow_extra_keys:
            result.append(
                Error(
                    'Extra keys present: {}'.format(', '.join(
                        six.text_type(key) for key in sorted(extra_keys))),
                    code=ERROR_CODE_UNKNOWN,
                ), )

        if not result and self.additional_validator:
            return self.additional_validator.errors(value)

        return result
예제 #3
0
    def errors(self, value):
        if not isinstance(value, Mapping):
            return [Error('Not a mapping (dictionary)')]

        # check for extra keys (object is allowed in case this gets validated twice)
        extra_keys = [
            k for k in six.iterkeys(value)
            if k not in ('path', 'kwargs', 'object')
        ]
        if extra_keys:
            return [
                Error(
                    'Extra keys present: {}'.format(', '.join(
                        six.text_type(k) for k in sorted(extra_keys))),
                    code=ERROR_CODE_UNKNOWN,
                )
            ]

        sentinel = object()
        path = value.get('path', sentinel)
        if path is sentinel and not self.default_path:
            return [
                Error('Missing key (and no default specified): path',
                      code=ERROR_CODE_MISSING,
                      pointer='path')
            ]

        if not path or path is sentinel:
            path = self.default_path

        errors = self._populate_schema_cache_if_necessary(path)
        if errors:
            return [update_error_pointer(e, 'path') for e in errors]

        if isinstance(value, MutableMapping):
            value['path'] = path  # in case it was defaulted
            if self.add_class_object_to_dict:
                value['object'] = PythonPath.resolve_python_path(path)

        return [
            update_error_pointer(e, 'kwargs')
            for e in self._schema_cache[path].errors(value.get('kwargs', {}))
        ]
예제 #4
0
    def errors(self, value):
        if not isinstance(value, self.valid_types):
            return [Error(self.type_error)]

        result = []
        if self.max_length is not None and len(value) > self.max_length:
            result.append(
                Error('List is longer than {}'.format(self.max_length)), )
        elif self.min_length is not None and len(value) < self.min_length:
            result.append(
                Error('List is shorter than {}'.format(self.min_length)), )
        for lazy_pointer, element in self._enumerate(value):
            result.extend(
                update_error_pointer(error, lazy_pointer.get())
                for error in (self.contents.errors(element) or []))
        return result
예제 #5
0
    def errors(self, value):
        if not isinstance(value, tuple):
            return [Error('Not a tuple')]

        result = []
        if len(value) != len(self.contents):
            result.append(
                Error(
                    'Number of elements {} does not match expected {}'.format(
                        len(value), len(self.contents))))

        for i, (c_elem, v_elem) in enumerate(zip(self.contents, value)):
            result.extend(
                update_error_pointer(error, i)
                for error in (c_elem.errors(v_elem) or []))

        return result
예제 #6
0
    def errors(self, value):  # type: (AnyType) -> ListType[Error]
        if not isinstance(value, tuple):
            return [Error('Not a tuple')]

        result = []
        if len(value) != len(self.contents):
            result.append(
                Error(
                    'Number of elements {} does not match expected {}'.format(
                        len(value), len(self.contents))))

        for i, (c_elem, v_elem) in enumerate(zip(self.contents, value)):
            result.extend(
                update_error_pointer(error, i)
                for error in (c_elem.errors(v_elem) or []))

        if not result and self.additional_validator:
            return self.additional_validator.errors(value)

        return result