def _validate_value_type(self, key, value): if value is None: return datatype = self.meta.structure.get(key) if isinstance(datatype, basestring): # A text reference, i.e. "self" or document class name. return if issubclass(datatype, Document) and isinstance(value, basestring): # A class reference; value is the PK, not the document object. # This is a normal situation when a document instance is being # created from a database record. The reference will be resolved # later on __getitem__ call. We just skip it for now. return if isinstance(datatype, OneToManyRelation): if not hasattr(value, '__iter__'): msg = u'{cls}.{field}: expected list of documents, got {value}' raise validators.ValidationError( msg.format(cls=type(self).__name__, field=key, value=repr(value))) return if datatype and not isinstance(value, datatype): msg = u'{cls}.{field}: expected a {datatype} instance, got {value}' raise validators.ValidationError( msg.format(cls=type(self).__name__, field=key, datatype=datatype.__name__, value=repr(value)))
def validate_length(self): import classbuilder import validators if getattr(self, 'minItems', None) is not None: if len(self.data) < self.minItems: raise validators.ValidationError( "{1} has too few elements. Wanted {0}.".format( self.minItems, self.data)) if getattr(self, 'maxItems', None) is not None: if len(self.data) > self.maxItems: raise validators.ValidationError( "{1} has too few elements. Wanted {0}.".format( self.maxItems, self.data))
def validate_items(self): import classbuilder import validators if self.__itemtype__ is None: return if not isinstance(self.__itemtype__, (tuple, list)): self.__itemtype__ = [ self.__itemtype__ for x in xrange(len(self.data)) ] if len(self.__itemtype__) > len(self.data): raise validators.ValidationError( "{1} does not have sufficient elements to validate against {0}" .format(self.__itemtype__, self.data)) typed_elems = [] for i, elem in enumerate(self.data): try: typ = self.__itemtype__[i] except IndexError: # It's actually permissible to run over a tuple constraint. pass if isinstance(typ, dict): for param, paramval in typ.iteritems(): validator = getattr(validators, param, None) if validator is not None: if param == 'minimum': validator(paramval, elem, info.get('exclusiveMinimum', False)) elif param == 'maximum': validator(paramval, elem, info.get('exclusiveMaximum', False)) else: validator(paramval, elem) elif issubclass(typ, classbuilder.LiteralValue): val = typ(elem) val.validate() typed_elems.append(val) elif issubclass(typ, classbuilder.ProtocolBase): if not isinstance(elem, typ): try: val = typ(**elem) except TypeError: raise ValidationError( "'{0}' was not a valid value for '{1}'".format( elem, typ)) else: val = elem val.validate() typed_elems.append(val) elif issubclass(typ, ArrayValidator): val = typ(elem) val.validate() typed_elems.append(val) return typed_elems
def validate_uniqueness(self): import classbuilder import validators if getattr(self, 'uniqueItems', None) is not None: testset = set(self.data) if len(testset) != len(self.data): raise validators.ValidationError( "{0} had duplicate elements, but uniqueness required". format(self.data))
def _validate_value_custom(self, key, value): tests = self.meta.validators.get(key, []) for test in tests: try: test(self, value) except validators.StopValidation: break except validators.ValidationError: # XXX should preserve call stack and add sensible message msg = 'Value {value} is invalid for {cls}.{field} ({test})' raise validators.ValidationError( msg.format(value=repr(value), cls=type(self).__name__, field=key, test=test))