-
-
Notifications
You must be signed in to change notification settings - Fork 595
Description
Hi, I have a question regarding the change in 4.10.0 and the default filling custom validator suggested here.
Before this version, I could use this enhanced validator to fill in default values even across "$ref"s to different schema.
But 4.10.0 added support "for referencing schemas with $ref
across different versions of the specification", which means that now the validator is determined dynamically based on the "$schema" and the custom one is not used for the referred schema.
Here is an example:
outer:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"count": {
"default": 0,
"type": "integer"
},
"nested": {
"$ref": "file://nested.json"
}
}
}
nested:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"nestedcount": {
"default": 0,
"type": "integer"
},
"name": {
"type": "string"
}
}
}
script:
import copy
import json
import jsonschema
def extend_with_default(validator_class):
validate_properties = validator_class.VALIDATORS["properties"]
def set_defaults(validator, properties, instance, schema):
for property, subschema in properties.items():
if "default" in subschema:
instance.setdefault(property, subschema["default"])
for error in validate_properties(
validator, properties, instance, schema,
):
yield error
return jsonschema.validators.extend(
validator_class, {"properties" : set_defaults},
)
Draft4ValidatorWithDefaults = extend_with_default(jsonschema.Draft4Validator)
def load_schema(uri):
with open(uri.removeprefix("file://")) as ifile:
return json.load(ifile)
schema = load_schema("outer.json")
resolver = jsonschema.RefResolver(
"outer.json", schema,
handlers={"file": load_schema})
validator_with_defaults = Draft4ValidatorWithDefaults(schema, resolver=resolver)
validator = jsonschema.Draft4Validator(schema, resolver=resolver)
content = {
"nested": {"name": "foo"}
}
print(jsonschema.__version__)
validator.validate(content)
print(content)
validator_with_defaults.validate(content)
print(content)
When I run this with jsonschema 4.9.1, I get:
4.9.1
{'nested': {'name': 'foo'}}
{'nested': {'name': 'foo', 'nestedcount': 0}, 'count': 0}
when I use 4.10.0, it looks like this:
4.10.0
{'nested': {'name': 'foo'}}
{'nested': {'name': 'foo'}, 'count': 0}
My question is, is there a way to revert to the previous behavior? I found out that when I delete the "$schema" key from the referred schema, it works as before, but that doesn't seem exactly nice (and I am not sure that won't cause other issues)...