summaryrefslogtreecommitdiff
path: root/jsonschema
diff options
context:
space:
mode:
authorJulian Berman <Julian@GrayVines.com>2023-02-23 15:35:44 +0200
committerJulian Berman <Julian@GrayVines.com>2023-02-23 16:12:31 +0200
commit19bdf6191a8e209584b18e7a3d4ec55cad9037e6 (patch)
treeb406a160255aaa084018ccde678a97b08b525edd /jsonschema
parent3801d9aea0e044ff8b190bff750594aa18dee67e (diff)
downloadjsonschema-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__.py36
-rw-r--r--jsonschema/exceptions.py20
-rw-r--r--jsonschema/tests/test_cli.py6
-rw-r--r--jsonschema/tests/test_deprecations.py48
-rw-r--r--jsonschema/tests/test_format.py3
-rw-r--r--jsonschema/tests/test_validators.py6
-rw-r--r--jsonschema/validators.py6
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}",
)