Skip to content

Commit a60a087

Browse files
committed
Support validator classes whose metaschema uses a different dialect.
In other words, one may author validator classes (via jsonschema.validators.create or extend) whose meta schema defines schema behavior using JSON Schema draft2020-12 but whose schemas are in its own dialect. Said again differently, the set of valid schemas for a validator class may be governed by one draft, while the schema behavior itself is governed by another.
1 parent edaf2a1 commit a60a087

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

CHANGELOG.rst

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
v4.13.0
2+
=======
3+
4+
* Add support for creating validator classes whose metaschema uses a different
5+
dialect than its schemas. In other words, they may use draft2020-12 to define
6+
which schemas are valid, but the schemas themselves use draft7 (or a custom
7+
dialect, etc.) to define which *instances* are valid. Doing this is likely
8+
not something most users, even metaschema authors, may need, but occasionally
9+
will be useful for advanced use cases.
10+
111
v4.12.1
212
=======
313

jsonschema/tests/test_validators.py

+32
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,38 @@ def test_create_default_types(self):
197197
),
198198
)
199199

200+
def test_check_schema_with_different_metaschema(self):
201+
"""
202+
One can create a validator class whose metaschema uses a different
203+
dialect than itself.
204+
"""
205+
206+
NoEmptySchemasValidator = validators.create(
207+
meta_schema={
208+
"$schema": validators.Draft202012Validator.META_SCHEMA["$id"],
209+
"not": {"const": {}},
210+
},
211+
)
212+
NoEmptySchemasValidator.check_schema({"foo": "bar"})
213+
214+
with self.assertRaises(exceptions.SchemaError):
215+
NoEmptySchemasValidator.check_schema({})
216+
217+
NoEmptySchemasValidator({"foo": "bar"}).validate("foo")
218+
219+
def test_check_schema_with_different_metaschema_defaults_to_self(self):
220+
"""
221+
A validator whose metaschema doesn't declare $schema defaults to its
222+
own validation behavior, not the latest "normal" specification.
223+
"""
224+
225+
NoEmptySchemasValidator = validators.create(
226+
meta_schema={"fail": [{"message": "Meta schema whoops!"}]},
227+
validators={"fail": fail},
228+
)
229+
with self.assertRaises(exceptions.SchemaError):
230+
NoEmptySchemasValidator.check_schema({})
231+
200232
def test_extend(self):
201233
original = dict(self.Validator.VALIDATORS)
202234
new = object()

jsonschema/validators.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ def __attrs_post_init__(self):
215215

216216
@classmethod
217217
def check_schema(cls, schema):
218-
for error in cls(cls.META_SCHEMA).iter_errors(schema):
218+
Validator = validator_for(cls.META_SCHEMA, default=cls)
219+
for error in Validator(cls.META_SCHEMA).iter_errors(schema):
219220
raise exceptions.SchemaError.create_from(error)
220221

221222
def evolve(self, **changes):

0 commit comments

Comments
 (0)