From dafe121e7e501a84f1c97f3073e78bb3c7542f33 Mon Sep 17 00:00:00 2001 From: Atsuo Ishimoto Date: Fri, 28 Jul 2023 08:27:09 +0900 Subject: [PATCH] Preserve $ref history. --- jsonschema/exceptions.py | 5 ++++- jsonschema/tests/test_validators.py | 12 ++++++++++++ jsonschema/validators.py | 4 ++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/jsonschema/exceptions.py b/jsonschema/exceptions.py index 80281057..66a81401 100644 --- a/jsonschema/exceptions.py +++ b/jsonschema/exceptions.py @@ -51,6 +51,7 @@ def __init__( schema_path=(), parent=None, type_checker=_unset, + refs=() ): super().__init__( message, @@ -63,6 +64,7 @@ def __init__( schema, schema_path, parent, + refs, ) self.message = message self.path = self.relative_path = deque(path) @@ -74,6 +76,7 @@ def __init__( self.instance = instance self.schema = schema self.parent = parent + self.refs = deque(refs) self._type_checker = type_checker for error in context: @@ -156,7 +159,7 @@ def _set(self, type_checker=None, **kwargs): def _contents(self): attrs = ( "message", "cause", "context", "validator", "validator_value", - "path", "schema_path", "instance", "schema", "parent", + "path", "schema_path", "instance", "schema", "parent", "refs", ) return dict((attr, getattr(self, attr)) for attr in attrs) diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 940a86da..6d19eae4 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -1485,6 +1485,18 @@ def test_ref_sibling(self): ), ) + def test_ref_history(self): + schema = { + "$defs": {"foo": {"properties":{"prop":{"$ref":"#/$defs/bar"},},}, + "bar": {"properties":{"a":{"type":"integer"},},},}, + "$ref": "#/$defs/foo" + } + instance = {"prop": {"a":"1",}} + + validator = validators._LATEST_VERSION(schema) + e, = list(validator.iter_errors(instance)) + self.assertEqual(list(e.refs), ["#/$defs/foo", "#/$defs/bar"]) + class MetaSchemaTestsMixin: # TODO: These all belong upstream diff --git a/jsonschema/validators.py b/jsonschema/validators.py index d5b4fcda..1ebe7bbe 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -369,6 +369,8 @@ def iter_errors(self, instance, _schema=None): schema=_schema, type_checker=self.TYPE_CHECKER, ) + if k == "$ref": + error.refs.appendleft(v) if k not in {"if", "$ref"}: error.schema_path.appendleft(k) yield error @@ -417,6 +419,8 @@ def descend( schema=schema, type_checker=evolved.TYPE_CHECKER, ) + if k == "$ref": + error.refs.appendleft(v) if k not in {"if", "$ref"}: error.schema_path.appendleft(k) if path is not None: