def validate(self,request): request = self.resolveAliases(request) s = self._schema skeys = set([ x for x in s.keys() if x[0] != '_' ]) rkeys = set(request.keys()) cloning = {} # if request has keywords which are not in the schema, we # shutdown straight away if not skeys.issuperset(rkeys): raise ValueError('Unknown keyword(s) in %s: %s' % (self._name,', '.join(rkeys.difference(skeys)))) # if the request does not have keywords which are required, we also # shutdown straight away (they could have a default value though # in that case we assign them). required = [] for key in skeys.difference(rkeys): if s[key]['required']: required.append(key) excludes = [] for key in s: if 'excludes' in s[key]: excluded = set() excluded.add(key) for ex in s[key]['excludes']: excluded.add(ex) excludes.append(excluded) if 'cloneinto' in s[key]: targets = [] for target in s[key]['cloneinto']: if not target in request: targets.append(target) cloning[key] = targets allexcluded = set() for group in excludes: allexcluded = allexcluded.union(group) if len(required) > 0: remaining = [] for key in required: if 'default' in s[key]: request[key] = s[key]['default'] elif not key in allexcluded: remaining.append(key) if len(remaining) > 0: raise ValueError('Required keyword(s) are missing in %s: %s' % (self._name,', '.join(remaining))) for group in excludes: v,r = self.find_excluded(request,group,s) if len(v) == 0: if len(r) > 0: raise ValueError('In "%s", at least one of "%s" is required' % (self._name,', '.join(group))) elif len(v) > 1: raise ValueError('In "%s", only one of "%s" is required, your specifed "%s"' % (self._name,', '.join(group), ', '.join(v))) # deal with lists and non-lists # also expand sub-schemas for k,i in request.items(): if not s[k]['uncountable']: if s[k]['unique']: if is_sequence_and_not_string(i) and len(i) > 1: raise ValueError('In %s, the keyword "%s" allows one value, not a list' % (self._name,k)) request[k] = no_list(i) else: request[k] = make_list(i) #if len(request[k]) == 0 and s[k]['required']: # raise ValueError('In %s, the keyword "%s" cannot be an empty list' % (self._name,k)) sub_schema = self.hasSchema(k,s[k],request) if sub_schema is not None: if s[k]['unique']: lang = Language(sub_schema,schemapath=self._schemapath) request[k] = lang.validate(i) else: i = make_list(i) for index,entry in enumerate(i): lang = Language(sub_schema,schemapath=self._schemapath) i[index] = lang.validate(entry) # now validate the values in the request if we can for k,i in request.items(): if "type" in s[k]: request[k] = self.createType(s[k]["type"],request[k]) if 'validate' in s[k]: assert(Validate.isRegistered(s[k]['validate'][0])) f = Validate.create(s[k]['validate'][0],*s[k]['validate'][1:]) request[k] = f(self._schemaNames,k,request[k],request) # as a last thing we clone whatever needs to be cloned for clone, targets in cloning.items(): if clone in request: for target in targets: if not s[clone]['unique'] and s[target]['unique']: request[target] = request[clone][0] else: request[target] = request[clone] return request