def from_json_schema_type(data: dict, type_string: str, allow_null: bool, definitions: SchemaDefinitions) -> Field: """ Build a typed field from a JSON schema object. """ if type_string == "number": kwargs = { "allow_null": allow_null, "minimum": data.get("minimum", None), "maximum": data.get("maximum", None), "exclusive_minimum": data.get("exclusiveMinimum", None), "exclusive_maximum": data.get("exclusiveMaximum", None), "multiple_of": data.get("multipleOf", None), "default": data.get("default", NO_DEFAULT), } return Float(**kwargs) elif type_string == "integer": kwargs = { "allow_null": allow_null, "minimum": data.get("minimum", None), "maximum": data.get("maximum", None), "exclusive_minimum": data.get("exclusiveMinimum", None), "exclusive_maximum": data.get("exclusiveMaximum", None), "multiple_of": data.get("multipleOf", None), "default": data.get("default", NO_DEFAULT), } return Integer(**kwargs) elif type_string == "string": min_length = data.get("minLength", 0) kwargs = { "allow_null": allow_null, "allow_blank": min_length == 0, "min_length": min_length if min_length > 1 else None, "max_length": data.get("maxLength", None), "format": data.get("format"), "pattern": data.get("pattern", None), "default": data.get("default", NO_DEFAULT), } return String(**kwargs) elif type_string == "boolean": kwargs = { "allow_null": allow_null, "default": data.get("default", NO_DEFAULT) } return Boolean(**kwargs) elif type_string == "array": items = data.get("items", None) if items is None: items_argument: typing.Union[None, Field, typing.List[Field]] = None elif isinstance(items, list): items_argument = [ from_json_schema(item, definitions=definitions) for item in items ] else: items_argument = from_json_schema(items, definitions=definitions) additional_items = data.get("additionalItems", None) if additional_items is None: additional_items_argument: typing.Union[bool, Field] = True elif isinstance(additional_items, bool): additional_items_argument = additional_items else: additional_items_argument = from_json_schema( additional_items, definitions=definitions) kwargs = { "allow_null": allow_null, "min_items": data.get("minItems", 0), "max_items": data.get("maxItems", None), "additional_items": additional_items_argument, "items": items_argument, "unique_items": data.get("uniqueItems", False), "default": data.get("default", NO_DEFAULT), } return Array(**kwargs) elif type_string == "object": properties = data.get("properties", None) if properties is None: properties_argument: typing.Optional[typing.Dict[str, Field]] = None else: properties_argument = { key: from_json_schema(value, definitions=definitions) for key, value in properties.items() } pattern_properties = data.get("patternProperties", None) if pattern_properties is None: pattern_properties_argument: typing.Optional[typing.Dict[ str, Field]] = (None) else: pattern_properties_argument = { key: from_json_schema(value, definitions=definitions) for key, value in pattern_properties.items() } additional_properties = data.get("additionalProperties", None) if additional_properties is None: additional_properties_argument: typing.Union[None, bool, Field] = (None) elif isinstance(additional_properties, bool): additional_properties_argument = additional_properties else: additional_properties_argument = from_json_schema( additional_properties, definitions=definitions) property_names = data.get("propertyNames", None) if property_names is None: property_names_argument: typing.Optional[Field] = None else: property_names_argument = from_json_schema(property_names, definitions=definitions) kwargs = { "allow_null": allow_null, "properties": properties_argument, "pattern_properties": pattern_properties_argument, "additional_properties": additional_properties_argument, "property_names": property_names_argument, "min_properties": data.get("minProperties", None), "max_properties": data.get("maxProperties", None), "required": data.get("required", None), "default": data.get("default", NO_DEFAULT), } return Object(**kwargs) assert False, f"Invalid argument type_string={type_string!r}" # pragma: no cover
def test_float(): validator = Float() value, error = validator.validate_or_error(123.1) assert value == 123.1 validator = Float() value, error = validator.validate_or_error(123) assert value == 123.0 validator = Float() value, error = validator.validate_or_error("123.1") assert value == 123.1 validator = Float() value, error = validator.validate_or_error(None) assert error == ValidationError(text="May not be null.", code="null") validator = Float() value, error = validator.validate_or_error("abc") assert error == ValidationError(text="Must be a number.", code="type") validator = Float() value, error = validator.validate_or_error(True) assert error == ValidationError(text="Must be a number.", code="type") validator = Float() value, error = validator.validate_or_error(float("inf")) assert error == ValidationError(text="Must be finite.", code="finite") validator = Float() value, error = validator.validate_or_error(float("nan")) assert error == ValidationError(text="Must be finite.", code="finite") validator = Float() value, error = validator.validate_or_error("123", strict=True) assert error == ValidationError(text="Must be a number.", code="type") validator = Float(allow_null=True) value, error = validator.validate_or_error(None) assert value is None assert error is None validator = Float(maximum=10.0) value, error = validator.validate_or_error(100.0) assert error == ValidationError(text="Must be less than or equal to 10.0.", code="maximum") validator = Float(maximum=10.0) value, error = validator.validate_or_error(10.0) assert value == 10.0 validator = Float(minimum=3.0) value, error = validator.validate_or_error(1.0) assert error == ValidationError( text="Must be greater than or equal to 3.0.", code="minimum") validator = Float(minimum=3.0) value, error = validator.validate_or_error(3.0) assert value == 3.0 validator = Float(exclusive_maximum=10.0) value, error = validator.validate_or_error(10.0) assert error == ValidationError(text="Must be less than 10.0.", code="exclusive_maximum") validator = Float(exclusive_minimum=3.0) value, error = validator.validate_or_error(3.0) assert error == ValidationError(text="Must be greater than 3.0.", code="exclusive_minimum") validator = Float(precision="0.01") value, error = validator.validate_or_error("123.456") assert value == 123.46 validator = Float(multiple_of=0.05, precision="0.01") value, error = validator.validate_or_error("123.05") assert value == 123.05 validator = Float(multiple_of=0.05, precision="0.01") value, error = validator.validate_or_error("123.06") assert error == ValidationError(text="Must be a multiple of 0.05.", code="multiple_of")