Skip to content

Commit d35f2c2

Browse files
committed
Only use a default (remote retrieving registry) when none is provided.
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
1 parent 685578a commit d35f2c2

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

jsonschema/tests/test_validators.py

+28
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
import tempfile
1313
import warnings
1414

15+
from referencing.jsonschema import DRAFT202012
1516
import attr
17+
import referencing.exceptions
1618

1719
from jsonschema import (
1820
FormatChecker,
@@ -2146,6 +2148,32 @@ def validate():
21462148
self.assertEqual((thread.is_alive(), failed), (False, []))
21472149

21482150

2151+
class TestReferencing(TestCase):
2152+
def test_registry_with_retrieve(self):
2153+
def retrieve(uri):
2154+
return DRAFT202012.create_resource({"type": "integer"})
2155+
2156+
registry = referencing.Registry(retrieve=retrieve)
2157+
schema = {"$ref": "https://example.com/"}
2158+
validator = validators.Draft202012Validator(schema, registry=registry)
2159+
2160+
self.assertEqual(
2161+
(validator.is_valid(12), validator.is_valid("foo")),
2162+
(True, False),
2163+
)
2164+
2165+
def test_custom_registries_do_not_autoretrieve_remote_resources(self):
2166+
registry = referencing.Registry()
2167+
schema = {"$ref": "https://example.com/"}
2168+
validator = validators.Draft202012Validator(schema, registry=registry)
2169+
2170+
with warnings.catch_warnings(record=True) as w:
2171+
warnings.simplefilter("always")
2172+
with self.assertRaises(referencing.exceptions.Unresolvable):
2173+
validator.validate(12)
2174+
self.assertFalse(w)
2175+
2176+
21492177
class TestRefResolver(TestCase):
21502178

21512179
base_uri = ""

jsonschema/validators.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def _warn_for_remote_retrieve(uri: str):
120120
return referencing.Resource.from_contents(json.load(response))
121121

122122

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

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

270270
def __attrs_post_init__(self):
271271
if self._resolver is None:
272-
registry = _DEFAULT_REGISTRY.combine(self._registry)
272+
registry = self._registry
273+
if registry is not _REMOTE_WARNING_REGISTRY:
274+
registry = SPECIFICATIONS.combine(registry)
273275
resource = specification.create_resource(self.schema)
274276
self._resolver = registry.resolver_with_root(resource)
275277

0 commit comments

Comments
 (0)