diff options
author | Julian Berman <Julian@GrayVines.com> | 2023-02-23 15:35:44 +0200 |
---|---|---|
committer | Julian Berman <Julian@GrayVines.com> | 2023-02-23 16:12:31 +0200 |
commit | 19bdf6191a8e209584b18e7a3d4ec55cad9037e6 (patch) | |
tree | b406a160255aaa084018ccde678a97b08b525edd /jsonschema | |
parent | 3801d9aea0e044ff8b190bff750594aa18dee67e (diff) | |
download | jsonschema-19bdf6191a8e209584b18e7a3d4ec55cad9037e6.tar.gz |
Three more exception-related deprecations.
* RefResolutionError is deprecated entirely.
Use referencing.Registry-based APIs, and catch
referencing.exceptions.Unresolvable if you really want to ignore
referencing related issues.
* FormatError should now be imported from jsonschema.exceptions
only, not from the package root.
* ErrorTree should now be imported from jsonschema.exceptions
only, not from the package root.
Diffstat (limited to 'jsonschema')
-rw-r--r-- | jsonschema/__init__.py | 36 | ||||
-rw-r--r-- | jsonschema/exceptions.py | 20 | ||||
-rw-r--r-- | jsonschema/tests/test_cli.py | 6 | ||||
-rw-r--r-- | jsonschema/tests/test_deprecations.py | 48 | ||||
-rw-r--r-- | jsonschema/tests/test_format.py | 3 | ||||
-rw-r--r-- | jsonschema/tests/test_validators.py | 6 | ||||
-rw-r--r-- | jsonschema/validators.py | 6 |
7 files changed, 106 insertions, 19 deletions
diff --git a/jsonschema/__init__.py b/jsonschema/__init__.py index 8f6b0a4..ad7affc 100644 --- a/jsonschema/__init__.py +++ b/jsonschema/__init__.py @@ -12,13 +12,7 @@ import warnings from jsonschema._format import FormatChecker from jsonschema._types import TypeChecker -from jsonschema.exceptions import ( - ErrorTree, - FormatError, - RefResolutionError, - SchemaError, - ValidationError, -) +from jsonschema.exceptions import SchemaError, ValidationError from jsonschema.protocols import Validator from jsonschema.validators import ( Draft3Validator, @@ -55,6 +49,34 @@ def __getattr__(name): stacklevel=2, ) return _RefResolver + elif name == "ErrorTree": + warnings.warn( + "Importing ErrorTree directly from the jsonschema package " + "is deprecated and will become an ImportError. Import it from " + "jsonschema.exceptions instead.", + DeprecationWarning, + stacklevel=2, + ) + from jsonschema.exceptions import ErrorTree + return ErrorTree + elif name == "FormatError": + warnings.warn( + "Importing FormatError directly from the jsonschema package " + "is deprecated and will become an ImportError. Import it from " + "jsonschema.exceptions instead.", + DeprecationWarning, + stacklevel=2, + ) + from jsonschema.exceptions import FormatError + return FormatError + elif name == "RefResolutionError": + from jsonschema.exceptions import _RefResolutionError + warnings.warn( + _RefResolutionError._DEPRECATION_MESSAGE, + DeprecationWarning, + stacklevel=2, + ) + return _RefResolutionError format_checkers = { "draft3_format_checker": Draft3Validator, diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index 149d838..5e88d74 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -9,6 +9,7 @@ from textwrap import dedent, indent from typing import ClassVar import heapq import itertools +import warnings import attr @@ -20,6 +21,17 @@ STRONG_MATCHES: frozenset[str] = frozenset() _unset = _utils.Unset() +def __getattr__(name): + if name == "RefResolutionError": + warnings.warn( + _RefResolutionError._DEPRECATION_MESSAGE, + DeprecationWarning, + stacklevel=2, + ) + return _RefResolutionError + raise AttributeError(f"module {__name__} has no attribute {name}") + + class _Error(Exception): _word_for_schema_in_error_message: ClassVar[str] @@ -181,11 +193,17 @@ class SchemaError(_Error): @attr.s(hash=True) -class RefResolutionError(Exception): +class _RefResolutionError(Exception): """ A ref could not be resolved. """ + _DEPRECATION_MESSAGE = ( + "jsonschema.exceptions.RefResolutionError is deprecated as of version " + "4.18.0. If you wish to catch potential reference resolution errors, " + "directly catch referencing.exceptions.Unresolvable." + ) + _cause = attr.ib() def __str__(self): diff --git a/jsonschema/tests/test_cli.py b/jsonschema/tests/test_cli.py index 84f8812..6d5873a 100644 --- a/jsonschema/tests/test_cli.py +++ b/jsonschema/tests/test_cli.py @@ -20,9 +20,9 @@ from pyrsistent import m from jsonschema import Draft4Validator, Draft202012Validator from jsonschema.exceptions import ( - RefResolutionError, SchemaError, ValidationError, + _RefResolutionError, ) from jsonschema.validators import _LATEST_VERSION, validate @@ -747,7 +747,7 @@ class TestCLI(TestCase): schema = '{"$ref": "someNonexistentFile.json#definitions/num"}' instance = "1" - with self.assertRaises(RefResolutionError) as e: + with self.assertRaises(_RefResolutionError) as e: self.assertOutputs( files=dict( some_schema=schema, @@ -766,7 +766,7 @@ class TestCLI(TestCase): schema = '{"$ref": "foo.json#definitions/num"}' instance = "1" - with self.assertRaises(RefResolutionError) as e: + with self.assertRaises(_RefResolutionError) as e: self.assertOutputs( files=dict( some_schema=schema, diff --git a/jsonschema/tests/test_deprecations.py b/jsonschema/tests/test_deprecations.py index 224f459..2beb02f 100644 --- a/jsonschema/tests/test_deprecations.py +++ b/jsonschema/tests/test_deprecations.py @@ -3,7 +3,7 @@ import importlib import subprocess import sys -from jsonschema import FormatChecker, validators +from jsonschema import FormatChecker, exceptions, validators class TestDeprecations(TestCase): @@ -28,6 +28,33 @@ class TestDeprecations(TestCase): with self.assertWarnsRegex(DeprecationWarning, message) as w: from jsonschema.validators import ErrorTree # noqa + self.assertEqual(ErrorTree, exceptions.ErrorTree) + self.assertEqual(w.filename, __file__) + + def test_import_ErrorTree(self): + """ + As of v4.18.0, importing ErrorTree from the package root is + deprecated in favor of doing so from jsonschema.exceptions. + """ + + message = "Importing ErrorTree directly from the jsonschema package " + with self.assertWarnsRegex(DeprecationWarning, message) as w: + from jsonschema import ErrorTree # noqa + + self.assertEqual(ErrorTree, exceptions.ErrorTree) + self.assertEqual(w.filename, __file__) + + def test_import_FormatError(self): + """ + As of v4.18.0, importing FormatError from the package root is + deprecated in favor of doing so from jsonschema.exceptions. + """ + + message = "Importing FormatError directly from the jsonschema package " + with self.assertWarnsRegex(DeprecationWarning, message) as w: + from jsonschema import FormatError # noqa + + self.assertEqual(FormatError, exceptions.FormatError) self.assertEqual(w.filename, __file__) def test_validators_validators(self): @@ -123,6 +150,25 @@ class TestDeprecations(TestCase): from jsonschema.validators import RefResolver # noqa: F401, F811 self.assertEqual(w.filename, __file__) + def test_RefResolutionError(self): + """ + As of v4.18.0, RefResolutionError is deprecated in favor of directly + catching errors from the referencing library. + """ + + message = "jsonschema.exceptions.RefResolutionError is deprecated" + with self.assertWarnsRegex(DeprecationWarning, message) as w: + from jsonschema import RefResolutionError # noqa: F401 + + self.assertEqual(RefResolutionError, exceptions._RefResolutionError) + self.assertEqual(w.filename, __file__) + + with self.assertWarnsRegex(DeprecationWarning, message) as w: + from jsonschema.exceptions import RefResolutionError # noqa + + self.assertEqual(RefResolutionError, exceptions._RefResolutionError) + self.assertEqual(w.filename, __file__) + def test_Validator_subclassing(self): """ As of v4.12.0, subclassing a validator class produces an explicit diff --git a/jsonschema/tests/test_format.py b/jsonschema/tests/test_format.py index 5dd06cf..a5a1d0c 100644 --- a/jsonschema/tests/test_format.py +++ b/jsonschema/tests/test_format.py @@ -4,7 +4,8 @@ Tests for the parts of jsonschema related to the :kw:`format` keyword. from unittest import TestCase -from jsonschema import FormatChecker, FormatError, ValidationError +from jsonschema import FormatChecker, ValidationError +from jsonschema.exceptions import FormatError from jsonschema.validators import Draft4Validator BOOM = ValueError("Boom!") diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 2d50b71..6a5756b 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -2285,15 +2285,15 @@ class TestRefResolver(TestCase): ref = "foo://bar" resolver = validators._RefResolver("", {}, handlers={"foo": handler}) - with self.assertRaises(exceptions.RefResolutionError) as err: + with self.assertRaises(exceptions._RefResolutionError) as err: with resolver.resolving(ref): self.fail("Shouldn't get this far!") # pragma: no cover - self.assertEqual(err.exception, exceptions.RefResolutionError(error)) + self.assertEqual(err.exception, exceptions._RefResolutionError(error)) def test_helpful_error_message_on_failed_pop_scope(self): resolver = validators._RefResolver("", {}) resolver.pop_scope() - with self.assertRaises(exceptions.RefResolutionError) as exc: + with self.assertRaises(exceptions._RefResolutionError) as exc: resolver.pop_scope() self.assertIn("Failed to pop the scope", str(exc.exception)) diff --git a/jsonschema/validators.py b/jsonschema/validators.py index 8ed275b..bd13544 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -884,7 +884,7 @@ class _RefResolver: try: self._scopes_stack.pop() except IndexError: - raise exceptions.RefResolutionError( + raise exceptions._RefResolutionError( "Failed to pop the scope from an empty stack. " "`pop_scope()` should only be called once for every " "`push_scope()`", @@ -1000,7 +1000,7 @@ class _RefResolver: try: document = self.resolve_remote(url) except Exception as exc: - raise exceptions.RefResolutionError(exc) + raise exceptions._RefResolutionError(exc) return self.resolve_fragment(document, fragment) @@ -1054,7 +1054,7 @@ class _RefResolver: try: document = document[part] except (TypeError, LookupError): - raise exceptions.RefResolutionError( + raise exceptions._RefResolutionError( f"Unresolvable JSON pointer: {fragment!r}", ) |