예제 #1
0
    def test_generate_lambda_no_variables(self):
        with self.assertRaises(ValidationError) as context:
            generate_lambda("11 > 10")

        self.assertTrue("No variables were" in str(context.exception))
예제 #2
0
    def test_generate_lambda_not_x(self):
        with self.assertRaises(ValidationError) as context:
            generate_lambda("y > 10")

        self.assertTrue("Only the variable" in str(context.exception))
예제 #3
0
    def test_generate_lambda_more_than_one(self):
        with self.assertRaises(ValidationError) as context:
            generate_lambda("x > y > 10")

        self.assertTrue("Only one variable" in str(context.exception))
예제 #4
0
    def test_generate_lambda_invalid(self):
        with self.assertRaises(ValidationError) as context:
            generate_lambda("xxx.xxx.000")

        self.assertTrue("No parsable lambda" in str(context.exception))
예제 #5
0
    def test_generate_lambda_none(self):
        with self.assertRaises(ValidationError) as context:
            generate_lambda(None)

        self.assertTrue("No value was " in str(context.exception))
예제 #6
0
    def test_generate_lambda_valid(self):
        fxn = generate_lambda("x % 8192 == 0")

        self.assertTrue(fxn(8192))

        self.assertFalse(fxn(8193))
예제 #7
0
    def _field_method_from_dict(name: str, field_dict: dict):
        """ Takes the dict from a yaml schema and creates a field appropriate for Marshmallow.  """
        field_types = {
            "string":
            fields.Str(),
            "uuid":
            fields.UUID(),
            "uri":
            fields.Str(validate=MLSchemaValidators.validate_type_URI),
            "datetime":
            MLSchemaFields.DateTime(),
            "semver":
            fields.Str(validate=MLSchemaValidators.validate_type_semver),
            "allowed_schema_types":
            fields.Str(),
            "boolean":
            fields.Boolean(),
            "list":
            fields.List(fields.Raw()),
            "list_strings":
            fields.List(
                fields.Str(
                    validate=MLSchemaValidators.validate_type_string_cast)),
            "list_of_tensor_shapes":
            fields.List(fields.Tuple([fields.Str(),
                                      fields.List(fields.Int)])),
            "list_interfaces":
            fields.List(
                fields.Dict(
                    validate=MLSchemaValidators.validate_type_interfaces)),
            "workflow_steps":
            fields.Dict(
                validate=MLSchemaValidators.validate_type_workflow_steps),
            "tags":
            fields.List(fields.Tuple([fields.Str(), fields.Str()])),
            "path":
            fields.Str(validate=MLSchemaValidators.validate_type_path),
            "dict":
            fields.Dict(),
            "float":
            fields.Float(),
            "email":
            fields.Email(),
            "bucket":
            fields.Str(validate=MLSchemaValidators.validate_type_bucket),
            "int":
            fields.Int(),
        }

        try:
            if "meta" in field_dict:
                # The field is a meta field about the schema, so skip adding a method
                return None
            field_type = field_dict["type"].lower()
            field_declaration = field_types[field_type]
        except KeyError:
            raise AttributeError(
                f"MLSchema Library has no field type named '{field_type}''")

        # Need to put this first so that we can redeclare the field function. Tried
        # attaching the regex without using the fields.Str(validate=) format,
        # and it didn't seem to work.
        if "regex" in field_dict:
            try:
                re.compile(field_dict["regex"])
            except re.error:
                raise AssertionError(
                    f"The regex ('{field_dict['regex']}') does not appear to be a valid regex."
                )

            field_declaration = fields.Str(validate=validate.Regexp(
                field_dict["regex"], error=f"No match for in field: {name}"))

        if "allowed" in field_dict:
            # TODO: This may be a bug in waiting - would prefer not to overwrite, but instead
            # just to add. Filed a bug with marshmallow to see.
            # TODO: Bug - cannot currently support with "list"
            field_declaration = fields.Str(
                validate=validate.OneOf(field_dict["allowed"]))

        if "constraint" in field_dict:
            # TODO: There's probably a better place for this - it's validating
            # the constraint on an int or float that it's actually in the correct form but
            # isn't changing anything else.
            if field_type not in ["int", "float"]:
                raise ValueError(
                    "Attempting to add a 'constraint' to a field that does not appear to be a 'float' or 'int'."
                )
            if field_type == "int":
                field_declaration = fields.Int(
                    validate=generate_lambda(field_dict["constraint"]))
            elif field_type == "float":
                field_declaration = fields.Float(
                    validate=generate_lambda(field_dict["constraint"]))
            else:
                raise ValueError("Don't know how you got here.")

        if "required" in field_dict and util.strtobool(
                MLSchemaValidators.validate_bool_and_return_string(
                    field_dict["required"])):
            field_declaration.required = True
        else:
            field_declaration.allow_none = True

        if "empty" in field_dict and util.strtobool(
                MLSchemaValidators.validate_bool_and_return_string(
                    field_dict["empty"])):
            field_declaration.allow_none = True

        return field_declaration