Skip to content

Commit

Permalink
Only use a default (remote retrieving registry) when none is provided.
Browse files Browse the repository at this point in the history
In other words when someone does *not* do Validator(..., registry=...)

This both limits the case which we *do* still perform automatic remote
ref retrieval (in a way that still preserves backwards compatibility
given that the registry argument did not previously exist, so someone
using it must be doing something new) as well as fixes an issue with
creating a validator with a registry that has a retrieve function.

Previously the latter raised a ValueError (coming from referencing which
doesn't want you combining registries unless they agree about retrieval
functions. See the added test(s) for details).

Fixes the issue mentioned here:

#1065 (comment)

Refs: #1089
  • Loading branch information
Julian committed Jun 12, 2023
1 parent 685578a commit d35f2c2
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
28 changes: 28 additions & 0 deletions jsonschema/tests/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
import tempfile
import warnings

from referencing.jsonschema import DRAFT202012
import attr
import referencing.exceptions

from jsonschema import (
FormatChecker,
Expand Down Expand Up @@ -2146,6 +2148,32 @@ def validate():
self.assertEqual((thread.is_alive(), failed), (False, []))


class TestReferencing(TestCase):
def test_registry_with_retrieve(self):
def retrieve(uri):
return DRAFT202012.create_resource({"type": "integer"})

registry = referencing.Registry(retrieve=retrieve)
schema = {"$ref": "https://example.com/"}
validator = validators.Draft202012Validator(schema, registry=registry)

self.assertEqual(
(validator.is_valid(12), validator.is_valid("foo")),
(True, False),
)

def test_custom_registries_do_not_autoretrieve_remote_resources(self):
registry = referencing.Registry()
schema = {"$ref": "https://example.com/"}
validator = validators.Draft202012Validator(schema, registry=registry)

with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
with self.assertRaises(referencing.exceptions.Unresolvable):
validator.validate(12)
self.assertFalse(w)


class TestRefResolver(TestCase):

base_uri = ""
Expand Down
8 changes: 5 additions & 3 deletions jsonschema/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def _warn_for_remote_retrieve(uri: str):
return referencing.Resource.from_contents(json.load(response))


_DEFAULT_REGISTRY = SPECIFICATIONS.combine(
_REMOTE_WARNING_REGISTRY = SPECIFICATIONS.combine(
referencing.Registry(retrieve=_warn_for_remote_retrieve), # type: ignore[call-arg] # noqa: E501
)

Expand Down Expand Up @@ -224,7 +224,7 @@ class Validator:
format_checker: _format.FormatChecker | None = field(default=None)
# TODO: include new meta-schemas added at runtime
_registry: referencing.jsonschema.SchemaRegistry = field(
default=referencing.Registry(),
default=_REMOTE_WARNING_REGISTRY,
kw_only=True,
repr=False,
)
Expand Down Expand Up @@ -269,7 +269,9 @@ def evolve(self, **changes):

def __attrs_post_init__(self):
if self._resolver is None:
registry = _DEFAULT_REGISTRY.combine(self._registry)
registry = self._registry
if registry is not _REMOTE_WARNING_REGISTRY:
registry = SPECIFICATIONS.combine(registry)
resource = specification.create_resource(self.schema)
self._resolver = registry.resolver_with_root(resource)

Expand Down

0 comments on commit d35f2c2

Please sign in to comment.