Skip to content

Commit d16713a

Browse files
committed
Merge remote-tracking branch 'datawire/better-patternProperties-errors-316'
* datawire/better-patternProperties-errors-316: Address review comments. Better error message for additionalProperties: false when there are patternProperties.
2 parents 4cd2268 + 124b81a commit d16713a

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

jsonschema/_validators.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,21 @@ def additionalProperties(validator, aP, instance, schema):
2929
for error in validator.descend(instance[extra], aP, path=extra):
3030
yield error
3131
elif not aP and extras:
32-
error = "Additional properties are not allowed (%s %s unexpected)"
33-
yield ValidationError(error % _utils.extras_msg(extras))
32+
if "patternProperties" in schema:
33+
patterns = sorted(schema["patternProperties"])
34+
if len(extras) == 1:
35+
verb = "does"
36+
else:
37+
verb = "do"
38+
error = "%s %s not match any of the regexes: %s" % (
39+
", ".join(map(repr, sorted(extras))),
40+
verb,
41+
", ".join(map(repr, patterns)),
42+
)
43+
yield ValidationError(error)
44+
else:
45+
error = "Additional properties are not allowed (%s %s unexpected)"
46+
yield ValidationError(error % _utils.extras_msg(extras))
3447

3548

3649
def items(validator, items, instance, schema):

jsonschema/tests/test_validators.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,30 @@ def test_invalid_format_default_message(self):
191191
self.assertIn(repr("thing"), message)
192192
self.assertIn("is not a", message)
193193

194+
def test_additionalProperties_false_patternProperties(self):
195+
schema = {u"type": u"object",
196+
u"additionalProperties": False,
197+
u"patternProperties": {
198+
u"^abc$": {u"type": u"string"},
199+
u"^def$": {u"type": u"string"}
200+
}}
201+
message = self.message_for({u"zebra": 123}, schema,
202+
cls=Draft4Validator)
203+
self.assertEqual(
204+
message,
205+
"{} does not match any of the regexes: {}, {}".format(
206+
repr(u"zebra"), repr(u"^abc$"), repr(u"^def$"),
207+
),
208+
)
209+
message = self.message_for({u"zebra": 123, u"fish": 456}, schema,
210+
cls=Draft4Validator)
211+
self.assertEqual(
212+
message,
213+
"{}, {} do not match any of the regexes: {}, {}".format(
214+
repr(u"fish"), repr(u"zebra"), repr(u"^abc$"), repr(u"^def$")
215+
),
216+
)
217+
194218

195219
class TestValidationErrorDetails(unittest.TestCase):
196220
# TODO: These really need unit tests for each individual validator, rather

0 commit comments

Comments
 (0)