Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error resolving sub-schema property with type object or array #97

Open
aciba90 opened this issue Jun 9, 2022 · 3 comments
Open

Error resolving sub-schema property with type object or array #97

aciba90 opened this issue Jun 9, 2022 · 3 comments

Comments

@aciba90
Copy link

aciba90 commented Jun 9, 2022

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.4
  • hypothesis==6.47.0
  • hypothesis-jsonschema==0.22.0
  • jsonschema==4.6.0
@Stranger6667
Copy link
Contributor

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

@aciba90
Copy link
Author

aciba90 commented Jun 22, 2022

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

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<À+'}

@aciba90
Copy link
Author

aciba90 commented Jun 22, 2022

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants