def _validate_getitemschema(schema: GetItemSchema, value): item = schema.item if type( schema.item) is tuple and not schema.strict else (schema.item, ) idx = 0 key = None try: for key in item: if iselement(value): value = value.attrib[key] elif isinstance(value, Match): value = value.group(key) else: value = value[key] idx += 1 return value except (KeyError, IndexError): # only return default value on last item in nested lookup if idx < len(item) - 1: raise ValidationError( "Item {key} was not found in object {value}", key=repr(key), value=repr(value), schema=GetItemSchema, ) return schema.default except (TypeError, AttributeError) as err: raise ValidationError( "Could not get key {key} from object {value}", key=repr(key), value=repr(value), schema=GetItemSchema, context=err, )
def check_url(value): validate(str, value) parsed = urlparse(value) if not parsed.netloc: raise ValidationError( "{value} is not a valid URL", value=repr(value), schema="url", ) for name, schema in attributes.items(): if not hasattr(parsed, name): raise ValidationError( "Invalid URL attribute {name}", name=repr(name), schema="url", ) try: validate(schema, getattr(parsed, name)) except ValidationError as err: raise ValidationError( "Unable to validate URL attribute {name}", name=repr(name), schema="url", context=err, ) return True
def _validate_attrschema(schema: AttrSchema, value): new = copy(value) for key, subschema in schema.schema.items(): if not hasattr(value, key): raise ValidationError( "Attribute {key} not found on object {value}", key=repr(key), value=repr(value), schema=AttrSchema, ) try: value = validate(subschema, getattr(value, key)) except ValidationError as err: raise ValidationError( "Could not validate attribute {key}", key=repr(key), schema=AttrSchema, context=err, ) setattr(new, key, value) return new
def _validate_xmlelementschema(schema, value): # type: (XmlElementSchema) validate(iselement, value) tag = value.tag attrib = value.attrib text = value.text tail = value.tail if schema.tag is not None: try: tag = validate(schema.tag, value.tag) except ValidationError as err: raise ValidationError( "Unable to validate XML tag: {0}".format(err), schema=XmlElementSchema, context=err) if schema.attrib is not None: try: attrib = validate(schema.attrib, OrderedDict(value.attrib)) except ValidationError as err: raise ValidationError( "Unable to validate XML attributes: {0}".format(err), schema=XmlElementSchema, context=err) if schema.text is not None: try: text = validate(schema.text, value.text) except ValidationError as err: raise ValidationError( "Unable to validate XML text: {0}".format(err), schema=XmlElementSchema, context=err) if schema.tail is not None: try: tail = validate(schema.tail, value.tail) except ValidationError as err: raise ValidationError( "Unable to validate XML tail: {0}".format(err), schema=XmlElementSchema, context=err) new = Element(tag, attrib) new.text = text new.tail = tail for child in value: new.append(deepcopy(child)) return new
def _validate_dict(schema, value): cls = type(schema) validate(cls, value) new = cls() for key, subschema in schema.items(): if isinstance(key, OptionalSchema): if key.key not in value: continue key = key.key if type(key) in (type, AllSchema, AnySchema, TransformSchema, UnionSchema): for subkey, subvalue in value.items(): try: newkey = validate(key, subkey) except ValidationError as err: raise ValidationError("Unable to validate key", schema=dict, context=err) try: newvalue = validate(subschema, subvalue) except ValidationError as err: raise ValidationError("Unable to validate value", schema=dict, context=err) new[newkey] = newvalue break if key not in value: raise ValidationError( "Key {key} not found in {value}", key=repr(key), value=repr(value), schema=dict, ) try: new[key] = validate(subschema, value[key]) except ValidationError as err: raise ValidationError( "Unable to validate value of key {key}", key=repr(key), schema=dict, context=err, ) return new
def _validate_unionschema(schema: UnionSchema, value): try: return validate_union(schema.schema, value) except ValidationError as err: raise ValidationError("Could not validate union", schema=UnionSchema, context=err)
def _validate_anyschema(schema: AnySchema, value): errors = [] for subschema in schema.schema: try: return validate(subschema, value) except ValidationError as err: errors.append(err) raise ValidationError(*errors, schema=AnySchema)
def _validate_callable(schema: abc.Callable, value): if not schema(value): raise ValidationError( "{callable} is not true", callable=f"{schema.__name__}({value!r})", schema=abc.Callable, ) return value
def validate(schema, value): if schema != value: raise ValidationError( "{value} does not equal {expected}", value=repr(value), expected=repr(schema), schema="equality", ) return value
def min_len(value): if not len(value) >= number: raise ValidationError( "Minimum length is {number}, but value is {value}", number=repr(number), value=len(value), schema="length", ) return True
def _validate_callable(schema, value): # type: (Callable) if not schema(value): raise ValidationError( "{callable} is not true", callable="{0}({1!r})".format(schema.__name__, value), schema=Callable, ) return value
def _validate_type(schema, value): if not isinstance(value, schema): raise ValidationError( "Type of {value} should be {expected}, but is {actual}", value=repr(value), expected=schema.__name__, actual=type(value).__name__, schema=type, ) return value
def contains_str(value): validate(str, value) if string not in value: raise ValidationError( "{value} does not contain {string}", value=repr(value), string=repr(string), schema="contains", ) return True
def ends_with(value): validate(str, value) if not value.endswith(string): raise ValidationError( "{value} does not end with {string}", value=repr(value), string=repr(string), schema="endswith", ) return True
def starts_with(value): validate(str, value) if not value.startswith(string): raise ValidationError( "{value} does not start with {string}", value=repr(value), string=repr(string), schema="startswith", ) return True
def xpath_find(value): validate(iselement, value) value = value.find(xpath) if value is None: raise ValidationError( "XPath {xpath} did not return an element", xpath=repr(xpath), schema="xml_find", ) return validate(iselement, value)
def _validate_type(schema, value): if is_py2 and type(value) == unicode: value = str(value) if schema == text_type: schema = str if not isinstance(value, schema): raise ValidationError( "Type of {value} should be {expected}, but is {actual}", value=repr(value), expected=schema.__name__, actual=type(value).__name__, schema=type, ) return value
def _validate_union_dict(schema, value): new = type(schema)() for key, schema in schema.items(): is_optional = isinstance(key, OptionalSchema) if is_optional: key = key.key try: new[key] = validate(schema, value) except ValidationError as err: if is_optional: continue raise ValidationError( "Unable to validate union {key}", key=repr(key), schema=dict, context=err, ) return new
def validate_union(schema, value): raise ValidationError( "Invalid union type: {type}", type=type(schema).__name__, )