summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.rst11
-rw-r--r--jsonschema/tests/test_validators.py32
-rw-r--r--jsonschema/validators.py2
3 files changed, 44 insertions, 1 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 0795665..add473f 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,3 +1,14 @@
+v4.10.1
+-------
+
+* Fix Validator.evolve (and APIs like ``iter_errors`` which call it) for cases
+ where the validator class has been subclassed. Doing so wasn't intended to be
+ public API, but given it didn't warn or raise an error it's of course
+ understandable. The next release however will make it warn (and a future one
+ will make it error). If you need help migrating usage of inheriting from a
+ validator class feel free to open a discussion and I'll try to give some
+ guidance (#982).
+
v4.10.0
-------
diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py
index 0643362..87fa1ed 100644
--- a/jsonschema/tests/test_validators.py
+++ b/jsonschema/tests/test_validators.py
@@ -1463,6 +1463,38 @@ class ValidatorTestMixin(MetaSchemaTestsMixin, object):
with self.assertRaises(exceptions.ValidationError):
validator.validate(None)
+ def test_evolve(self):
+ ref, schema = "someCoolRef", {"type": "integer"}
+ resolver = validators.RefResolver("", {}, store={ref: schema})
+
+ validator = self.Validator(schema, resolver=resolver)
+ new = validator.evolve(schema={"type": "string"})
+
+ expected = self.Validator({"type": "string"}, resolver=resolver)
+
+ self.assertEqual(new, expected)
+ self.assertNotEqual(new, validator)
+
+ def test_evolve_with_subclass(self):
+ """
+ Subclassing validators isn't supported public API, but some users have
+ done it, because we don't actually error entirely when it's done :/
+
+ We need to deprecate doing so first to help as many of these users
+ ensure they can move to supported APIs, but this test ensures that in
+ the interim, we haven't broken those users.
+ """
+
+ @attr.s
+ class OhNo(self.Validator):
+ foo = attr.ib(factory=lambda: [1, 2, 3])
+
+ validator = OhNo({})
+ self.assertEqual(validator.foo, [1, 2, 3])
+
+ new = validator.evolve(schema={"type": "integer"})
+ self.assertEqual(new.foo, [1, 2, 3])
+
def test_it_delegates_to_a_legacy_ref_resolver(self):
"""
Legacy RefResolvers support only the context manager form of
diff --git a/jsonschema/validators.py b/jsonschema/validators.py
index 4d6ced0..c799d40 100644
--- a/jsonschema/validators.py
+++ b/jsonschema/validators.py
@@ -203,7 +203,7 @@ def create(
def evolve(self, **changes):
schema = changes.setdefault("schema", self.schema)
- NewValidator = validator_for(schema, default=Validator)
+ NewValidator = validator_for(schema, default=self.__class__)
# Essentially reproduces attr.evolve, but may involve instantiating
# a different class than this one.