diff options
-rw-r--r-- | jsonschema/exceptions.py | 10 | ||||
-rw-r--r-- | jsonschema/tests/test_deprecations.py | 34 | ||||
-rw-r--r-- | jsonschema/validators.py | 7 |
3 files changed, 50 insertions, 1 deletions
diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index d1ee50a..2ad9d3c 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -11,6 +11,7 @@ import heapq import itertools import warnings +from referencing.exceptions import Unresolvable as _Unresolvable import attr from jsonschema import _utils @@ -210,6 +211,15 @@ class _RefResolutionError(Exception): return str(self._cause) +class _WrappedReferencingError(_RefResolutionError, _Unresolvable): + def __init__(self, cause: _Unresolvable): + object.__setattr__(self, "_cause", cause) + + def __getattribute__(self, attr): + cause = object.__getattribute__(self, "_cause") + return getattr(cause, attr) + + class UndefinedTypeCheck(Exception): """ A type checker was asked to check a type it did not have registered. diff --git a/jsonschema/tests/test_deprecations.py b/jsonschema/tests/test_deprecations.py index 2beb02f..cf5538f 100644 --- a/jsonschema/tests/test_deprecations.py +++ b/jsonschema/tests/test_deprecations.py @@ -3,6 +3,8 @@ import importlib import subprocess import sys +import referencing.exceptions + from jsonschema import FormatChecker, exceptions, validators @@ -169,6 +171,38 @@ class TestDeprecations(TestCase): self.assertEqual(RefResolutionError, exceptions._RefResolutionError) self.assertEqual(w.filename, __file__) + def test_catching_Unresolvable_directly(self): + """ + This behavior is the intended behavior (i.e. it's not deprecated), but + given we do "tricksy" things in the iterim to wrap exceptions in a + multiple inheritance subclass, we need to be extra sure it works and + stays working. + """ + validator = validators.Draft202012Validator({"$ref": "http://foo.com"}) + + with self.assertRaises(referencing.exceptions.Unresolvable) as e: + validator.validate(12) + + expected = referencing.exceptions.Unresolvable(ref="http://foo.com") + self.assertEqual(e.exception, expected) + + def test_catching_Unresolvable_via_RefResolutionError(self): + """ + Until RefResolutionError is removed, it is still possible to catch + exceptions from reference resolution using it, even though they may + have been raised by referencing. + """ + with self.assertWarns(DeprecationWarning): + from jsonschema import RefResolutionError + + validator = validators.Draft202012Validator({"$ref": "http://foo.com"}) + + with self.assertRaises(referencing.exceptions.Unresolvable): + validator.validate(12) + + with self.assertRaises(RefResolutionError): + validator.validate(12) + def test_Validator_subclassing(self): """ As of v4.12.0, subclassing a validator class produces an explicit diff --git a/jsonschema/validators.py b/jsonschema/validators.py index 23ea17c..72af8fc 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -19,6 +19,7 @@ from attrs import define, field, fields from jsonschema_specifications import REGISTRY as SPECIFICATIONS from referencing import Specification from rpds import HashTrieMap +import referencing.exceptions import referencing.jsonschema from jsonschema import ( @@ -401,7 +402,11 @@ def create( def _validate_reference(self, ref, instance): if self._ref_resolver is None: - resolved = self._resolver.lookup(ref) + try: + resolved = self._resolver.lookup(ref) + except referencing.exceptions.Unresolvable as err: + raise exceptions._WrappedReferencingError(err) + return self.descend( instance, resolved.contents, |