Skip to content

Commit

Permalink
Fix a regression with RefResolver-based resolution in newly created d…
Browse files Browse the repository at this point in the history
…rafts

We need a bit more state management to serve `RefResolver` until it's
fully removed :/

(The handler here is simply to avoid needing to hit some remote
reference.)

Refs: #1061 (comment)
  • Loading branch information
Julian committed Jul 12, 2023
1 parent 56d57e7 commit 90ea779
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.rst
@@ -1,3 +1,8 @@
v4.18.1
=======

* Fix a regression with ``jsonschema.RefResolver`` based resolution when used in combination with a custom validation dialect (via ``jsonschema.validators.create``).

v4.18.0
=======

Expand Down
22 changes: 22 additions & 0 deletions jsonschema/tests/test_validators.py
Expand Up @@ -2373,6 +2373,28 @@ def test_pointer_within_schema_with_different_id(self):
validator = validators.Draft7Validator(another, resolver=two)
self.assertFalse(validator.is_valid({"maxLength": "foo"}))

def test_newly_created_validator_with_ref_resolver(self):
"""
See https://github.com/python-jsonschema/jsonschema/issues/1061#issuecomment-1624266555.
""" # noqa: E501

def handle(uri):
self.assertEqual(uri, "http://example.com/foo")
return {"type": "integer"}

resolver = validators._RefResolver("", {}, handlers={"http": handle})
Validator = validators.create(
meta_schema={},
validators=validators.Draft4Validator.VALIDATORS,
)
schema = {"$id": "http://example.com/bar", "$ref": "foo"}
validator = Validator(schema, resolver=resolver)
self.assertEqual(
(validator.is_valid({}), validator.is_valid(37)),
(False, True),
)



def sorted_errors(errors):
def key(error):
Expand Down
5 changes: 5 additions & 0 deletions jsonschema/validators.py
Expand Up @@ -275,6 +275,11 @@ def __attrs_post_init__(self):
resource = specification.create_resource(self.schema)
self._resolver = registry.resolver_with_root(resource)

# REMOVEME: Legacy ref resolution state management.
push_scope = getattr(self._ref_resolver, "push_scope", None)
if push_scope is not None:
push_scope(id_of(self.schema))

@classmethod
def check_schema(cls, schema, format_checker=_UNSET):
Validator = validator_for(cls.META_SCHEMA, default=cls)
Expand Down

0 comments on commit 90ea779

Please sign in to comment.