diff options
-rw-r--r-- | CHANGELOG.rst | 11 | ||||
-rw-r--r-- | jsonschema/tests/test_validators.py | 32 | ||||
-rw-r--r-- | jsonschema/validators.py | 2 |
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. |