1

For my project I need a new property for json schemas. I named it "isPropertyOf" and basically what I want is that if I have this:

fruits = {
    "banana": "yellow fruit",
    "apple": "round fruit"
}

schema = {
    "type": "object",
    "properties": {
        "fav_fruit": {
            "type": "string",
            "isPropertyOf": fruits
        }
    }
}

Then schema would validate only objects like {"fav_fruit":"banana"} or {"fav_fruit":"apple"}, but not {"fav_fruit":"salami"} (I know that for this very example using an enum would make more sense, but assume "fruits" is also used for other stuff and I would rather avoid redundancy)

I read docs about this and figured I need to use jsonschema.validators.extend. I tried something like that:

def is_property_of_callable(validator_instance, property_value, instance, schema):
    keys = [k for k in property_value]
    return instance in keys

mapping = {"isPropertyOf": is_property_of_callable}
my_validator = jsonschema.validators.extend(jsonschema.Draft7Validator, mapping)
instance = {"fav_fruit": "tobacco"}
my_validator(schema).is_valid(instance)

I was ready to see something go wrong, but apparently the validator wasn't seeing any issue. I tried with an obviously wrong instance that even the standard validator of jsonschema wouldn't accept

my_validator(schema).is_valid({"fav_fruit": 0})

But apparently it looked ok to it. I thought maybe the way I added this property was so broken that it was making the validator accept anything, so I tried a minimal case of validator extension:

minimal_validator = jsonschema.validators.extend(jsonschema.Draft7Validator, {})
minimal_validator(schema).is_valid(instance)

And this one is also happy with 0 being my favourite fruit.

What am I doing wrong here? How can I make that work?

Anne Aunyme
  • 506
  • 4
  • 14

1 Answers1

0

The validators in jsonschema can only validate the errors by iter_errors.

So this line

return instance in keys

should be changed to generate the ValidationError, just like

if instance not in keys:
  yield ValidationError(f"{instance!r} not in {keys}")
  • Thank you for your answer! That was an old project, so I can't confirm it works just yet, but I will! Anyway, how would you explain the behavior of this minimal case? – Anne Aunyme May 10 '23 at 12:42