def init_format_value(self, v, rule, path): log.debug(u"Init format value : %s", path) if is_string(v): self._format = [v] elif isinstance(v, list): valid = True for date_format in v: if not isinstance(date_format, basestring): valid = False if valid: self._format = v else: raise RuleError( msg=u"All values in format list must be strings", error_key=u"format.not_string", path=path, ) else: raise RuleError( msg=u"Value of format keyword: '{}' must be a string or list or string values".format(v), error_key=u"format.not_string", path=path, ) valid_types = ("date", ) # Format is only supported when used with "type=date" if self._type not in valid_types: raise RuleError( msg="Keyword format is only allowed when used with the following types: {0}".format(valid_types), error_key=u"format.not_used_with_correct_type", path=path, )
def init_pattern_value(self, v, rule, path): """ """ log.debug(u"Init pattern value : %s", path) if not is_string(v): raise RuleError( msg=u"Value of pattern keyword: '{0}' 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: {0}".format(self.pattern_regexp), error_key=u"pattern.syntax_error", path=path, )
def init_pattern_value(self, v, rule, path): """ """ log.debug(u"Init pattern value : %s", path) if not is_string(v): raise RuleError( msg=u"Value of pattern keyword: '{0}' 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: {0}".format( self.pattern_regexp), error_key=u"pattern.syntax_error", path=path, )
def init_func(self, v, rule, path): """ """ if not is_string(v): raise RuleError( msg=u"Value: {0} for func keyword must be a string".format(v), error_key=u"func.notstring", path=path, ) self.func = v
def init_example(self, v, rule, path): log.debug(u'Init example value : {0}'.format(path)) if not is_string(v): 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_example(self, v, rule, path): log.debug(u'Init example value : {0}'.format(path)) if not is_string(v): 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_name_value(self, v, rule, path): """ """ log.debug(u"Init name value : %s", path) if not is_string(v): raise RuleError( msg=u"Value: {0} for keyword name must be a string".format(v), error_key=u"name.not_string", path=path, ) self.name = v
def init_desc_value(self, v, rule, path): """ """ log.debug(u"Init descr value : %s", path) if not is_string(v): 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
def _validate_length(self, rule, value, path, prefix): if not is_string(value): raise CoreError("Value: '{0}' must be a 'str' type for length check to work".format(value)) value_length = len(str(value)) max_, min_, max_ex, min_ex = rule.get('max'), rule.get('min'), rule.get('max-ex'), rule.get('min-ex') log.debug( u"Validate length : %s : %s : %s : %s : %s : %s", max, min, max_ex, min_ex, value, path, ) if max_ is not None and max_ < value_length: self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Value: '{value_str}' has length of '{value}', greater than max limit '{max_}'. Path: '{path}'", value_str=value, path=path, value=len(value), prefix=prefix, max_=max_)) if min_ is not None and min_ > value_length: self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Value: '{value_str}' has length of '{value}', greater than min limit '{min_}'. Path: '{path}'", value_str=value, path=path, value=len(value), prefix=prefix, min_=min_)) if max_ex is not None and max_ex <= value_length: self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Value: '{value_str}' has length of '{value}', greater than max_ex limit '{max_ex}'. Path: '{path}'", value_str=value, path=path, value=len(value), prefix=prefix, max_ex=max_ex)) if min_ex is not None and min_ex >= value_length: self.errors.append(SchemaError.SchemaErrorEntry( msg=u"Value: '{value_str}' has length of '{value}', greater than min_ex limit '{min_ex}'. Path: '{path}'", value_str=value, path=path, value=len(value), prefix=prefix, min_ex=min_ex))
def init_assert_value(self, v, rule, path): """ """ log.debug(u"Init assert value : %s", path) if not is_string(v): raise RuleError( msg=u"Value: '{0}' for keyword 'assert' is not a string".format(v), error_key=u"assert.not_str", path=path, ) self.assertion = v if any(k in self.assertion for k in (';', 'import', '__import__')): raise RuleError( msg=u"Value: '{assertion}' contain invalid content that is not allowed to be present in assertion keyword".format(assertion=self.assertion), error_key=u"assert.unsupported_content", path=path, )
def init_format_value(self, v, rule, path): log.debug(u"Init format value : %s", path) if is_string(v): self._format = [v] elif isinstance(v, list): valid = True for date_format in v: if not isinstance(date_format, basestring): valid = False if valid: self._format = v else: raise RuleError( msg=u"All values in format list must be strings", error_key=u"format.not_string", path=path, ) else: raise RuleError( msg= u"Value of format keyword: '{}' must be a string or list or string values" .format(v), error_key=u"format.not_string", path=path, ) valid_types = ("date", ) # Format is only supported when used with "type=date" if self._type not in valid_types: raise RuleError( msg= "Keyword format is only allowed when used with the following types: {0}" .format(valid_types), error_key=u"format.not_used_with_correct_type", path=path, )
def init_assert_value(self, v, rule, path): """ """ log.debug(u"Init assert value : %s", path) if not is_string(v): raise RuleError( msg=u"Value: '{0}' for keyword 'assert' is not a string". format(v), error_key=u"assert.not_str", path=path, ) self.assertion = v if any(k in self.assertion for k in (';', 'import', '__import__')): raise RuleError( msg= u"Value: '{assertion}' contain invalid content that is not allowed to be present in assertion keyword" .format(assertion=self.assertion), error_key=u"assert.unsupported_content", path=path, )
def init(self, schema, path): """ """ log.debug(u"Init schema: %s", schema) include = schema.get("include") # Check if this item is a include, overwrite schema with include schema and continue to parse if include: log.debug(u"Found include tag...") self.include_name = include return t = None rule = self if schema is not None: if "type" not in schema: # Mapping and sequence do not need explicit type defenitions if any(sa in schema for sa in sequence_aliases): t = "seq" self.init_type_value(t, rule, path) elif any(ma in schema for ma in mapping_aliases): t = "map" self.init_type_value(t, rule, path) else: t = DEFAULT_TYPE self.type = t else: if not is_string(schema["type"]): raise RuleError( msg=u"Key 'type' in schema rule is not a string type (found %s)" % type(schema["type"]).__name__, error_key=u"type.not_string", path=path, ) self.type = schema["type"] self.schema_str = schema if not t: t = schema["type"] self.init_type_value(t, rule, path) func_mapping = { "allowempty": self.init_allow_empty_map, "assert": self.init_assert_value, "class": lambda x, y, z: (), "default": self.init_default_value, "desc": self.init_desc_value, "enum": self.init_enum_value, "example": self.init_example, "extensions": self.init_extensions, "format": self.init_format_value, "func": self.init_func, "ident": self.init_ident_value, "length": self.init_length_value, "map": self.init_mapping_value, "mapping": self.init_mapping_value, "matching": self.init_matching, "matching-rule": self.init_matching_rule, "name": self.init_name_value, "nul": self.init_nullable_value, "nullable": self.init_nullable_value, "pattern": self.init_pattern_value, "range": self.init_range_value, "req": self.init_required_value, "required": self.init_required_value, "seq": self.init_sequence_value, "sequence": self.init_sequence_value, "type": lambda x, y, z: (), "unique": self.init_unique_value, "version": self.init_version, } for k, v in schema.items(): if k in func_mapping: func_mapping[k](v, rule, path) elif k.startswith("schema;"): # Schema tag is only allowed on top level of data log.debug(u"Found schema tag...") raise RuleError( msg=u"Schema is only allowed on top level of schema file", error_key=u"schema.not.toplevel", path=path, ) else: raise RuleError( msg=u"Unknown key: {0} found".format(k), error_key=u"key.unknown", path=path, ) self.check_conflicts(schema, rule, path) self.check_type_keywords(schema, rule, path)
def test_types(self): """ Test that all type helper methods works correctly """ assert types.type_class("str") == str assert types.is_builtin_type("str") assert types.is_collection_type("map") assert types.is_collection_type("seq") assert not types.is_collection_type("str") assert types.is_scalar_type("str") assert not types.is_scalar_type("seq") assert not types.is_scalar_type("map") assert types.is_collection([]) assert types.is_collection({}) assert not types.is_collection("foo") assert types.is_scalar("") assert types.is_scalar(True) assert not types.is_scalar([]) assert types.is_correct_type("", str) assert types.is_correct_type({}, dict) assert types.is_string("foo") assert not types.is_string([]) assert types.is_int(1) assert not types.is_int("foo") assert types.is_bool(True) assert not types.is_bool(1) assert not types.is_bool("true") assert types.is_float(1.0) assert not types.is_float("foo") assert types.is_number(1) assert types.is_number(1.0) assert not types.is_number("foo") assert types.is_text("foo") assert types.is_text(1) assert types.is_text(1.0) assert not types.is_text([]) assert not types.is_text(True) assert types.is_any("foo") assert types.is_any(True) assert types.is_any(1) assert types.is_any(1.0) assert types.is_any({}) assert types.is_any([]) assert types.is_enum("foo") assert not types.is_enum(1) assert types.is_none(None) assert not types.is_none("foo")
def test_types(self): """ Test that all type helper methods works correctly """ assert types.type_class("str") == str assert types.is_builtin_type("str") assert types.is_collection_type("map") assert types.is_collection_type("seq") assert not types.is_collection_type("str") assert types.is_scalar_type("str") assert not types.is_scalar_type("seq") assert not types.is_scalar_type("map") assert types.is_collection([]) assert types.is_collection({}) assert not types.is_collection("foo") assert types.is_scalar("") assert types.is_scalar(True) assert not types.is_scalar([]) assert types.is_correct_type("", str) assert types.is_correct_type({}, dict) assert types.is_string("foo") assert not types.is_string([]) assert types.is_int(1) assert not types.is_int("foo") assert types.is_bool(True) assert not types.is_bool(1) assert not types.is_bool("true") assert types.is_float(1.0) assert not types.is_float("foo") assert types.is_number(1) assert types.is_number(1.0) assert not types.is_number("foo") assert types.is_text("foo") assert types.is_text(1) assert types.is_text(1.0) assert not types.is_text([]) assert not types.is_text(True) assert types.is_any("foo") assert types.is_any(True) assert types.is_any(1) assert types.is_any(1.0) assert types.is_any({}) assert types.is_any([]) assert types.is_enum("foo") assert not types.is_enum(1) assert types.is_none(None) assert not types.is_none("foo") assert types.is_url("https://github.com")
def init(self, schema, path): """ """ log.debug(u"Init schema: %s", schema) include = schema.get("include") # Check if this item is a include, overwrite schema with include schema and continue to parse if include: log.debug(u"Found include tag...") self.include_name = include return t = None rule = self if schema is not None: if "type" not in schema: # Mapping and sequence do not need explicit type defenitions if any(sa in schema for sa in sequence_aliases): t = "seq" self.init_type_value(t, rule, path) elif any(ma in schema for ma in mapping_aliases): t = "map" self.init_type_value(t, rule, path) else: t = DEFAULT_TYPE self.type = t else: if not is_string(schema["type"]): raise RuleError( msg= u"Key 'type' in schema rule is not a string type (found %s)" % type(schema["type"]).__name__, error_key=u"type.not_string", path=path, ) self.type = schema["type"] self.schema_str = schema if not t: t = schema["type"] self.init_type_value(t, rule, path) func_mapping = { "allowempty": self.init_allow_empty_map, "assert": self.init_assert_value, "class": lambda x, y, z: (), "default": self.init_default_value, "desc": self.init_desc_value, "enum": self.init_enum_value, "example": self.init_example, "extensions": self.init_extensions, "format": self.init_format_value, "func": self.init_func, "ident": self.init_ident_value, "length": self.init_length_value, "map": self.init_mapping_value, "mapping": self.init_mapping_value, "matching": self.init_matching, "matching-rule": self.init_matching_rule, "name": self.init_name_value, "nul": self.init_nullable_value, "nullable": self.init_nullable_value, "pattern": self.init_pattern_value, "range": self.init_range_value, "req": self.init_required_value, "required": self.init_required_value, "seq": self.init_sequence_value, "sequence": self.init_sequence_value, "type": lambda x, y, z: (), "unique": self.init_unique_value, "version": self.init_version, } for k, v in schema.items(): if k in func_mapping: func_mapping[k](v, rule, path) elif k.startswith("schema;"): # Schema tag is only allowed on top level of data log.debug(u"Found schema tag...") raise RuleError( msg=u"Schema is only allowed on top level of schema file", error_key=u"schema.not.toplevel", path=path, ) else: raise RuleError( msg=u"Unknown key: {0} found".format(k), error_key=u"key.unknown", path=path, ) self.check_conflicts(schema, rule, path) self.check_type_keywords(schema, rule, path)