def init_sequence_value(self, v, rule, path): log.debug("Init sequence value : {}".format(path)) if v is not None and not isinstance(v, list): raise RuleError("sequence.notseq : {} : {}".format(v, path)) self._sequence = v if self._sequence is None or len(self._sequence) == 0: raise RuleError("sequence.noelem : {} : {}".format( self._sequence, path)) tmp_seq = [] for i, e in enumerate(self._sequence): elem = e or {} rule = Rule(None, self) rule.init(elem, "{}/sequence/{}".format(path, i)) tmp_seq.append(rule) self._sequence = tmp_seq return rule
def init_sequence_value(self, v, rule, path): log.debug(u"Init sequence value : %s", path) if v is not None and not isinstance(v, list): raise RuleError( msg=u"Sequence keyword is not a list", error_key=u"sequence.not_seq", path=path, ) self.sequence = v if self.sequence is None or len(self.sequence) == 0: raise RuleError( msg=u"Sequence contains 0 elements", error_key=u"sequence.no_elements", path=path, ) tmp_seq = [] for i, e in enumerate(self.sequence): elem = e or {} rule = Rule(None, self) rule.init(elem, u"{}/sequence/{}".format(path, i)) tmp_seq.append(rule) self.sequence = tmp_seq return rule
def init_unique_value(self, v, rule, path): """ """ log.debug(u"Init unique value : %s", path) if not isinstance(v, bool): raise RuleError( msg=u"Value: '{0}' for 'unique' keyword is not boolean".format( v), error_key=u"unique.not_bool", path=path, ) self.unique = v if is_collection_type(self.type): raise RuleError( msg= u"Type of the value: '{0}' for 'unique' keyword is not a scalar type" .format(self.type), error_key=u"unique.not_scalar", path=path, ) if path == "": raise RuleError( msg=u"Keyword 'unique' can't be on root level of schema", error_key=u"unique.not_on_root_level", path=path, )
def init_pattern_value(self, v, rule, path): log.debug(u"Init pattern value : %s", path) if not isinstance(v, str): raise RuleError( msg=u"Value of pattern keyword: '{}' is not a string".format(v), error_key=u"pattern.not_string", path=path, ) self.pattern = v if self.schema_str["type"] == "map": raise RuleError( msg=u"Keyword pattern is not allowed inside map", error_key=u"pattern.not_allowed_in_map", path=path, ) # TODO: Some form of validation of the regexp? it exists in the source try: self.pattern_regexp = re.compile(self.pattern) except Exception: raise RuleError( msg=u"Syntax error when compiling regex pattern: {}".format(self.pattern_regexp), error_key=u"pattern.syntax_error", path=path, )
def init_default_value(self, v, rule, path): """ """ log.debug(u"Init default value : %s", path) self.default = v if is_collection_type(self.type): raise RuleError( msg=u"Value: {0} for keyword 'default' is not a scalar type". format(v), error_key=u"default.not_scalar", path=path, ) if self.type == "map" or self.type == "seq": raise RuleError( msg=u"Value: {0} for keyword 'default' is not a scalar type". format(v), error_key=u"default.not_scalar", path=path, ) if not isinstance(v, self.type_class): raise RuleError( msg=u"Types do not match: '{0}' --> '{1}'".format( v, self.type_class), error_key=u"default.type.unmatch", path=path, )
def init_ident_value(self, v, rule, path): log.debug(u"Init ident value : %s", path) if v is None or isinstance(v, bool): raise RuleError( msg=u"Value: '{}' of 'ident' is not a boolean value".format(v), error_key=u"ident.not_bool", path=path, ) self.ident = bool(v) self.required = True if is_collection_type(self.type): raise RuleError( msg=u"Value: '{}' of 'ident' is not a scalar value".format(v), error_key=u"ident.not_scalar", path=path, ) if path == "": raise RuleError( msg=u"Keyword 'ident' can't be on root level of schema", error_key=u"ident.not_on_root_level", path=path, ) if self.parent is None or not self.parent.type == "map": raise RuleError( msg=u"Keword 'ident' can't be inside 'map'", error_key=u"ident.not_in_map", path=path, )
def init_enum_value(self, v, rule, path): log.debug(u"Init enum value : %s", path) if not isinstance(v, list): raise RuleError( msg=u"Enum is not a sequence", error_key=u"enum.not_seq", path=path, ) self.enum = v if is_collection_type(self.type): raise RuleError( msg=u"Enum is not a scalar", error_key=u"enum.not_scalar", path=path, ) lookup = set() for item in v: if not isinstance(item, self.type_class): raise RuleError( msg=u"Item: '{}' in enum is not of correct class type: '{}'".format(item, self.type_class), error_key=u"enum.type.unmatch", path=path, ) if item in lookup: raise RuleError( msg=u"Duplicate items: '{}' found in enum".format(item), error_key=u"enum.duplicate_items", path=path, ) lookup.add(item)
def initSequenceValue(self, v, rule, path): Log.debug("Init sequence value : {}".format(path)) if v is not None and not isinstance(v, list): raise RuleError("sequence.notseq : {} : {}".format(v, path)) self._sequence = v if self._sequence is None or len(self._sequence) == 0: raise RuleError("sequence.noelem : {} : {}".format(self._sequence, path)) if len(self._sequence) > 1: raise RuleError("sequence.toomany : {} : {}".format(self._sequence, path)) elem = self._sequence[0] if elem is None: elem = {} i = 0 rule = Rule(None, self) rule.init(elem, "{}/sequence/{}".format(path, i)) self._sequence = [] self._sequence.append(rule) return rule
def init_assert_value(self, v, rule, path): log.debug("Init assert value : {}".format(path)) if not isinstance(v, str): raise RuleError("assert.notstr : {}".format(path)) self._assert = v raise RuleError("assert.NYI-Error : {}".format(path))
def initDefaultValue(self, v, rule, path): Log.debug("Init default value : {}".format(path)) self._default = v if isCollectionType(self._type): raise RuleError("default.notscalar : {} : {} : {}".format(rule, path, v)) if self._type == "map" or self._type == "seq": raise RuleError("default.notscalar : {} : {} : {}".format(rule, os.path.dirname(path), v)) if not isinstance(v, self._type_class): raise RuleError("default.type.unmatch : {} --> {} : {}".format(v, self._type_class, path))
def initUniqueValue(self, v, rule, path): Log.debug("Init unique value : {}".format(path)) if not isinstance(v, bool): raise RuleError("unique.notbool : {} : {}".format(v, path)) self._unique = v if isCollectionType(self._type): raise RuleError("unique.notscalar : {} : {}".format(self._type, path)) if path == "": raise RuleError("unique.onroot")
def initPatternValue(self, v, rule, path): Log.debug("Init pattern value : {}".format(path)) if not isinstance(v, str): raise RuleError("pattern.notstr : {} : {}".format(v, path)) self._pattern = v # TODO: Some form of validation of the regexp? it exists in the source try: self._pattern_regexp = re.compile(self._pattern) except Exception: raise RuleError("pattern.syntaxerr : {} --> {} : {}".format(self._pattern_regexp, self._pattern_regexp, path))
def initIdentValue(self, v, rule, path): Log.debug("Init ident value : {}".format(path)) if v is None or isinstance(v, bool): raise RuleError("ident.notbool : {} : {}".format(v, path)) self._ident = bool(v) self._required = True if isCollectionType(self._type): raise RuleError("ident.notscalar : {} : {}".format(self._type, path)) if path == "": raise RuleError("ident.onroot") if self._parent is None or not self._parent._type == "map": raise RuleError("ident.notmap : {}".format(path))
def initTypeValue(self, v, rule, path): Log.debug("Init type value : {}".format(path)) Log.debug("Type: {} {}".format(v, rule)) if v is None: v = DEFAULT_TYPE if not isinstance(v, str): raise RuleError("type.nostr : {} : {}".format(v, path)) self._type = v self._type_class = typeClass(v) if not isBuiltinType(self._type): raise RuleError("type.unknown : {} : {}".format(self._type, path))
def init(self, schema, path): Log.debug("Init schema: {}".format(schema)) if schema is not None: # assert isinstance(schema, dict), "schema is not a dict : {}".format(path) if "type" not in schema: raise RuleError("key 'type' not found in schema rule : {}".format(path)) else: if not isinstance(schema["type"], str): raise RuleError("key 'type' in schema rule is not a string type : {}".format(path)) self._type = schema["type"] rule = self self._schema_str = schema t = schema["type"] self.initTypeValue(t, rule, path) func_mapping = { "type": lambda x, y, z: (), "name": self.initNameValue, "desc": self.initDescValue, "required": self.initRequiredValue, "pattern": self.initPatternValue, "enum": self.initEnumValue, "assert": self.initAssertValue, "range": self.initRangeValue, "length": self.initLengthValue, "ident": self.initIdentValue, "unique": self.initUniqueValue, "allowempty": self.initAllowEmptyMap, "default": self.initDefaultValue, "sequence": self.initSequenceValue, "mapping": self.initMappingValue, "matching-rule": self.initMatchingRule, } for k, v in schema.items(): if k in func_mapping: func_mapping[k](v, rule, path) else: raise RuleError("Unknown key: {} found : {}".format(k, path)) self.checkConfliction(schema, rule, path)
def init_mapping_value(self, v, rule, path): # Check for duplicate use of 'map' and 'mapping' if self._mapping: raise RuleError("mapping.multiple-use : {}".format(path)) log.debug("Init mapping value : {}".format(path)) if v is not None and not isinstance(v, dict): raise RuleError("mapping.notmap : {} : {}".format(v, path)) if v is None or len(v) == 0: raise RuleError("mapping.noelem : {} : {}".format(v, path)) self._mapping = {} self._regex_mappings = [] for k, v in v.items(): if v is None: v = {} # Check if this is a regex rule. Handle specially if k.startswith("regex;") or k.startswith("re;"): log.debug("Found regex map rule") regex = k.split(";", 1) if len(regex) != 2: raise RuleError("Malformed regex key : {}".format(k)) else: regex = regex[1] try: re.compile(regex) except Exception as e: raise RuleError( "Unable to compile regex '{}' '{}'".format( regex, e)) regex_rule = Rule(None, self) regex_rule.init( v, "{}/mapping;regex/{}".format(path, regex[1:-1])) regex_rule._map_regex_rule = regex[1:-1] self._regex_mappings.append(regex_rule) self._mapping[k] = regex_rule else: rule = Rule(None, self) rule.init(v, "{}/mapping/{}".format(path, k)) self._mapping[k] = rule return rule
def init_assert_value(self, v, rule, path): log.debug(u"Init assert value : %s", path) if not isinstance(v, str): raise RuleError( msg=u"Value: '{}' for keyword 'assert' is not a string".format(v), error_key=u"assert.not_str", path=path, ) self.assertion = v raise RuleError( msg=u"Keyword assert is not yet implemented", error_key=u"assert.NotYetImplemented", path=path, )
def init_func(self, v, rule, path): """ """ if not isinstance(v, str): raise RuleError( "value for func keyword must be a string : {} : {}".format( v, path)) self._func = v
def init_matching(self, v, rule, path): log.debug("Init matching rule : {}".format(path)) valid_values = ["any", "all", "*"] if str(v) not in valid_values: raise RuleError("matching value: {} is not one of {}".format( str(v), valid_values)) self._matching = str(v)
def init_required_value(self, v, rule, path): log.debug(u"Init required value : %s", path) if not isinstance(v, bool): raise RuleError( msg=u"Value: '{}' for required keyword must be a boolean".format(v), error_key=u"required.not_bool", path=path, ) self.required = v
def initEnumValue(self, v, rule, path): Log.debug("Init enum value : {}".format(path)) if not isinstance(v, list): raise RuleError("enum.notseq") self._enum = v if isCollectionType(self._type): raise RuleError("enum.notscalar") lookup = set() for item in v: if not isinstance(item, self._type_class): raise RuleError("enum.type.unmatch : {} --> {} : {}".format(item, self._type_class, path)) if item in lookup: raise RuleError("enum.duplicate : {} : {}".format(item, path)) lookup.add(item)
def initMatchingRule(self, v, rule, path): Log.debug("Init matching-rule: {}".format(path)) Log.debug("{} {}".format(v, rule)) # Verify that the provided rule is part of one of the allowed one allowed = ["any"] # ["none", "one", "all"] Is currently awaiting proper implementation if v not in allowed: raise RuleError("Specefied rule in key : {} is not part of allowed rule set : {}".format(v, allowed)) else: self._matching_rule = v
def init_extensions(self, v, rule, path): """ """ if not isinstance(v, list): raise RuleError( "Extension defenition should be a list : {} : {}".format( v, path)) # TODO: Add limitation that this keyword can only be used at the top level of the file self._extensions = v
def init_func(self, v, rule, path): """ """ if not isinstance(v, str): raise RuleError( msg=u"Value: {} for func keyword must be a string".format(v), error_key=u"func.notstring", path=path, ) self.func = v
def init_pattern_value(self, v, rule, path): log.debug("Init pattern value : {}".format(path)) if not isinstance(v, str): raise RuleError("pattern.notstr : {} : {}".format(v, path)) self._pattern = v if self._schema_str["type"] == "map": raise RuleError( "map.pattern : pattern not allowed inside map : {} : {}". format(v, path)) # TODO: Some form of validation of the regexp? it exists in the source try: self._pattern_regexp = re.compile(self._pattern) except Exception: raise RuleError("pattern.syntaxerr : {} --> {} : {}".format( self._pattern_regexp, self._pattern_regexp, path))
def init_type_value(self, v, rule, path): log.debug("Init type value : {}".format(path)) log.debug("Type: {} {}".format(v, rule)) if v is None: v = DEFAULT_TYPE self._type = v self._type_class = type_class(v) if not is_builtin_type(self._type): raise RuleError("type.unknown : {} : {}".format(self._type, path))
def init_example(self, v, rule, path): log.debug(u'Init example value : {0}'.format(path)) if not isinstance(v, basestring): raise RuleError( msg=u"Value: {0} for keyword example must be a string".format( v), error_key=u"example.not_string", path=path, ) self.desc = v
def init_matching(self, v, rule, path): log.debug(u"Init matching rule : %s", path) valid_values = ["any", "all", "*"] if str(v) not in valid_values: raise RuleError( msg=u"matching value: {} is not one of {}".format(str(v), valid_values), error_key=u"matching_rule.invalid", path=path, ) self.matching = str(v)
def init_extensions(self, v, rule, path): """ """ if not isinstance(v, list): raise RuleError( msg=u"Extension defenition should be a list", error_key=u"extension.not_list", path=path, ) # TODO: Add limitation that this keyword can only be used at the top level of the file self.extensions = v
def init_desc_value(self, v, rule, path): """ """ log.debug(u"Init descr value : %s", path) if not isinstance(v, basestring): raise RuleError( msg=u"Value: {0} for keyword desc must be a string".format(v), error_key=u"desc.not_string", path=path, ) self.desc = v