hypothesis-jsonschema
hypothesis-jsonschema copied to clipboard
Error resolving sub-schema property with type object or array
The following jsonschema provokes hypothesis-jsonschema to fail:
from hypothesis import given
from hypothesis_jsonschema import from_schema
schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"$defs": {
"def_foo": {
"properties": {
"foo": {"type": "string"}
},
"additionalProperties": False,
},
"def_bar": {
"type": "object",
"properties": {
"bar": {
"type": ["object", "array"],
"$ref": "#/$defs/def_foo",
"items": {
"type": "object",
"$ref": "#/$defs/def_foo",
},
},
},
},
},
"allOf": [
{"$ref": "#/$defs/def_bar"},
],
}
@given(from_schema(schema))
def test_dummy(instance):
assert True
Exception:
self = <hypothesis_jsonschema._resolve.LocalResolver object at 0x7f2a1058ce10>
document = {'additionalProperties': {'not': {}}, 'items': {'$ref': '#/$defs/def_foo', 'type': 'object'}, 'maxProperties': 1, 'properties': {'foo': {'type': 'string'}}, ...}
fragment = '$defs/def_foo'
def resolve_fragment(self, document, fragment):
"""
Resolve a ``fragment`` within the referenced ``document``.
Arguments:
document:
The referent document
fragment (str):
a URI fragment to resolve within it
"""
fragment = fragment.lstrip(u"/")
parts = unquote(fragment).split(u"/") if fragment else []
for part in parts:
part = part.replace(u"~1", u"/").replace(u"~0", u"~")
if isinstance(document, Sequence):
# Array indexes should be turned into integers
try:
part = int(part)
except ValueError:
pass
try:
document = document[part]
except (TypeError, LookupError):
raise exceptions.RefResolutionError(
> "Unresolvable JSON pointer: %r" % fragment
)
E jsonschema.exceptions.RefResolutionError: Unresolvable JSON pointer: '$defs/def_foo'
./venv/bin/python3.6/site-packages/jsonschema/validators.py:814: RefResolutionError
Environment:
Python version: 3.10.4hypothesis==6.47.0hypothesis-jsonschema==0.22.0jsonschema==4.6.0
hypothesis-jsonschema doesn't support JSON Schema drafts newer than Draft 7. I assume that it is the case, as $ref is used along with other keywords in $defs/bar/properties/pbar
hypothesis-jsonschemadoesn't support JSON Schema drafts newer than Draft 7. I assume that it is the case, as$refis used along with other keywords in$defs/bar/properties/pbar
It is a Draft 4 schema. We can see that hypothesis-jsonschema supports references with the following example:
import jsonschema
from hypothesis_jsonschema import from_schema
schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"$defs": {
"foo": {
"type": "object",
"properties": {"a": {"type": "string"}},
"additionalProperties": False
},
},
"allOf": [
{"$ref": "#/$defs/foo"},
],
}
jsonschema.validate({"a": "asdf"}, schema)
strategy = from_schema(schema)
print(strategy.example())
Executing the previous example outputs:
{'a': '\U0005c9f5<À+'}
I have updated the description with a schema containing the Draft version. I have realized that that schema seems to be not 100% correct as:
jsonschema.validate({"bar": {"foo": "asdf"}}, schema) # valid
jsonschema.validate({"bar": [{"foo": "asdf"}, {"foo": "asdf"}]}, schema) # valid
jsonschema.validate({"bar": ["0", 1]}, schema) # invalid
The last validation should raise, but it doesn't.
This could mean that is schema is not fully correct, but jsonschema does not raise a SchemaError, therefore it is treating it as valid.
From a hypothesis-jsonschema point of view, I still think the LocalResolver gets confused because:
We define an object and an array together In $defs.def_bar.properties.bar and the fragments are not correctly resolved in order.