Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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")