From 17fb9cb006402f68b9fbf3b6877a778135f0aecc Mon Sep 17 00:00:00 2001 From: Julian Berman Date: Thu, 3 Jan 2019 16:51:14 +0000 Subject: [PATCH] Make validate use best_match. This function is essentially meant to be the 'dead simple', newbie friendly entry into validation. Making it use best_match means even friendlier initial errors, so we switch to using that. Users who care about potential small effects this has on performance should already likely be using an explicitly constructed validator class, and choosing themselves whether to call best_match or not. Closes: #498 --- jsonschema/tests/test_validators.py | 16 +++++++++++----- jsonschema/validators.py | 6 +++++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 6c4e991b5..7a91f34fd 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -358,13 +358,12 @@ def test_multiple_type_failure(self): def test_object_without_title_type_failure(self): type = {u"type": [{u"minimum": 3}]} message = self.message_for(instance=1, schema={u"type": [type]}) - self.assertEqual(message, "1 is not of type %r" % (type,)) + self.assertEqual(message, "1 is less than the minimum of 3") - def test_object_with_name_type_failure(self): - name = "Foo" - schema = {u"type": [{u"name": name, u"minimum": 3}]} + def test_object_with_named_type_failure(self): + schema = {u"type": [{u"name": "Foo", u"minimum": 3}]} message = self.message_for(instance=1, schema=schema) - self.assertEqual(message, "1 is not of type %r" % (name,)) + self.assertEqual(message, "1 is less than the minimum of 3") def test_minimum(self): message = self.message_for(instance=1, schema={"minimum": 2}) @@ -1324,6 +1323,13 @@ def test_schema_error_message(self): "(?s)Failed validating u?'.*' in metaschema.*On schema", ) + def test_it_uses_best_match(self): + # This is a schema that best_match will recurse into + schema = {"oneOf": [{"type": "string"}, {"type": "array"}]} + with self.assertRaises(exceptions.ValidationError) as e: + validators.validate(12, schema) + self.assertIn("12 is not of type", str(e.exception)) + class TestRefResolver(SynchronousTestCase): diff --git a/jsonschema/validators.py b/jsonschema/validators.py index 6b7559fa9..8f0da7a2e 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -862,8 +862,12 @@ def validate(instance, schema, cls=None, *args, **kwargs): """ if cls is None: cls = validator_for(schema) + cls.check_schema(schema) - cls(schema, *args, **kwargs).validate(instance) + validator = cls(schema, *args, **kwargs) + error = exceptions.best_match(validator.iter_errors(instance)) + if error is not None: + raise error def validator_for(schema, default=_LATEST_VERSION):