Skip to content

Commit 841a0a2

Browse files
committed
#782: Code clenaup, fixes validation messages
1 parent 1caee54 commit 841a0a2

File tree

6 files changed

+93
-129
lines changed

6 files changed

+93
-129
lines changed

jsonschema/_legacy_validators.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ def dependencies_draft3(validator, dependencies, instance, schema):
2828

2929

3030
def dependencies_draft4_draft6_draft7(
31-
validator,
32-
dependencies,
33-
instance,
34-
schema,
31+
validator,
32+
dependencies,
33+
instance,
34+
schema,
3535
):
3636
"""
3737
Support for the ``dependencies`` validator from pre-draft 2019-09.

jsonschema/_utils.py

Lines changed: 57 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -255,55 +255,50 @@ def find_evaluated_item_indexes_by_schema(validator, instance, schema):
255255
Get all indexes of items that get evaluated under the current schema
256256
257257
Covers all keywords related to unevaluatedItems: items, prefixItems, if,
258-
then, else, 'contains', 'unevaluatedItems', 'allOf', 'oneOf', 'anyOf'
258+
then, else, contains, unevaluatedItems, allOf, oneOf, anyOf
259259
"""
260-
if not validator.is_type(schema, "object"):
260+
if validator.is_type(schema, "boolean"):
261261
return []
262262
evaluated_indexes = []
263263

264-
if 'items' in schema:
264+
if "items" in schema:
265265
return list(range(0, len(instance)))
266266

267-
if '$ref' in schema:
268-
resolve = getattr(validator.resolver, "resolve", None)
269-
if resolve:
270-
scope, resolved = validator.resolver.resolve(schema['$ref'])
271-
validator.resolver.push_scope(scope)
267+
if "$ref" in schema:
268+
scope, resolved = validator.resolver.resolve(schema["$ref"])
269+
validator.resolver.push_scope(scope)
272270

273-
try:
274-
evaluated_indexes += find_evaluated_item_indexes_by_schema(
275-
validator, instance, resolved)
276-
finally:
277-
validator.resolver.pop_scope()
278-
279-
if 'prefixItems' in schema:
280-
if validator.is_valid(
281-
instance, {'prefixItems': schema['prefixItems']}
282-
):
283-
evaluated_indexes += list(range(0, len(schema['prefixItems'])))
284-
285-
if 'if' in schema:
286-
if validator.is_valid(instance, schema['if']):
271+
try:
272+
evaluated_indexes += find_evaluated_item_indexes_by_schema(
273+
validator, instance, resolved)
274+
finally:
275+
validator.resolver.pop_scope()
276+
277+
if "prefixItems" in schema:
278+
evaluated_indexes += list(range(0, len(schema["prefixItems"])))
279+
280+
if "if" in schema:
281+
if validator.is_valid(instance, schema["if"]):
287282
evaluated_indexes += find_evaluated_item_indexes_by_schema(
288-
validator, instance, schema['if']
283+
validator, instance, schema["if"]
289284
)
290-
if 'then' in schema:
285+
if "then" in schema:
291286
evaluated_indexes += find_evaluated_item_indexes_by_schema(
292-
validator, instance, schema['then']
287+
validator, instance, schema["then"]
293288
)
294289
else:
295-
if 'else' in schema:
290+
if "else" in schema:
296291
evaluated_indexes += find_evaluated_item_indexes_by_schema(
297-
validator, instance, schema['else']
292+
validator, instance, schema["else"]
298293
)
299294

300-
for keyword in ['contains', 'unevaluatedItems']:
295+
for keyword in ["contains", "unevaluatedItems"]:
301296
if keyword in schema:
302297
for k, v in enumerate(instance):
303298
if validator.is_valid(v, schema[keyword]):
304299
evaluated_indexes.append(k)
305300

306-
for keyword in ['allOf', 'oneOf', 'anyOf']:
301+
for keyword in ["allOf", "oneOf", "anyOf"]:
307302
if keyword in schema:
308303
for subschema in schema[keyword]:
309304
errs = list(validator.descend(instance, subschema))
@@ -320,28 +315,26 @@ def find_evaluated_property_keys_by_schema(validator, instance, schema):
320315
Get all keys of items that get evaluated under the current schema
321316
322317
Covers all keywords related to unevaluatedProperties: properties,
323-
'additionalProperties', 'unevaluatedProperties', patternProperties,
324-
dependentSchemas, 'allOf', 'oneOf', 'anyOf', if, then, else
318+
additionalProperties, unevaluatedProperties, patternProperties,
319+
dependentSchemas, allOf, oneOf, anyOf, if, then, else
325320
"""
326-
if not validator.is_type(schema, "object"):
321+
if validator.is_type(schema, "boolean"):
327322
return []
328323
evaluated_keys = []
329324

330-
if '$ref' in schema:
331-
resolve = getattr(validator.resolver, "resolve", None)
332-
if resolve:
333-
scope, resolved = validator.resolver.resolve(schema['$ref'])
334-
validator.resolver.push_scope(scope)
325+
if "$ref" in schema:
326+
scope, resolved = validator.resolver.resolve(schema["$ref"])
327+
validator.resolver.push_scope(scope)
335328

336-
try:
337-
evaluated_keys += find_evaluated_property_keys_by_schema(
338-
validator, instance, resolved
339-
)
340-
finally:
341-
validator.resolver.pop_scope()
329+
try:
330+
evaluated_keys += find_evaluated_property_keys_by_schema(
331+
validator, instance, resolved
332+
)
333+
finally:
334+
validator.resolver.pop_scope()
342335

343336
for keyword in [
344-
'properties', 'additionalProperties', 'unevaluatedProperties'
337+
"properties", "additionalProperties", "unevaluatedProperties"
345338
]:
346339
if keyword in schema:
347340
if validator.is_type(schema[keyword], "boolean"):
@@ -356,27 +349,23 @@ def find_evaluated_property_keys_by_schema(validator, instance, schema):
356349
):
357350
evaluated_keys.append(property)
358351

359-
if 'patternProperties' in schema:
352+
if "patternProperties" in schema:
360353
for property, value in instance.items():
361-
for pattern, subschema in schema['patternProperties'].items():
362-
if re.search(pattern, property):
363-
if validator.is_valid(
364-
{property: value}, schema['patternProperties']
365-
):
366-
evaluated_keys.append(property)
367-
368-
if 'dependentSchemas' in schema:
369-
for property, subschema in schema['dependentSchemas'].items():
354+
for pattern, subschema in schema["patternProperties"].items():
355+
if re.search(pattern, property) and validator.is_valid(
356+
{property: value}, schema["patternProperties"]
357+
):
358+
evaluated_keys.append(property)
359+
360+
if "dependentSchemas" in schema:
361+
for property, subschema in schema["dependentSchemas"].items():
370362
if property not in instance:
371363
continue
364+
evaluated_keys += find_evaluated_property_keys_by_schema(
365+
validator, instance, subschema
366+
)
372367

373-
errs = list(validator.descend(instance, subschema))
374-
if not errs:
375-
evaluated_keys += find_evaluated_property_keys_by_schema(
376-
validator, instance, subschema
377-
)
378-
379-
for keyword in ['allOf', 'oneOf', 'anyOf']:
368+
for keyword in ["allOf", "oneOf", "anyOf"]:
380369
if keyword in schema:
381370
for subschema in schema[keyword]:
382371
errs = list(validator.descend(instance, subschema))
@@ -385,19 +374,19 @@ def find_evaluated_property_keys_by_schema(validator, instance, schema):
385374
validator, instance, subschema
386375
)
387376

388-
if 'if' in schema:
389-
if validator.is_valid(instance, schema['if']):
377+
if "if" in schema:
378+
if validator.is_valid(instance, schema["if"]):
390379
evaluated_keys += find_evaluated_property_keys_by_schema(
391-
validator, instance, schema['if']
380+
validator, instance, schema["if"]
392381
)
393-
if 'then' in schema:
382+
if "then" in schema:
394383
evaluated_keys += find_evaluated_property_keys_by_schema(
395-
validator, instance, schema['then']
384+
validator, instance, schema["then"]
396385
)
397386
else:
398-
if 'else' in schema:
387+
if "else" in schema:
399388
evaluated_keys += find_evaluated_property_keys_by_schema(
400-
validator, instance, schema['else']
389+
validator, instance, schema["else"]
401390
)
402391

403392
return evaluated_keys

jsonschema/_validators.py

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,7 @@ def contains(validator, contains, instance, schema):
129129
if min_contains == 0:
130130
return
131131

132-
matches = len(list(
133-
filter(lambda x: x, [validator.is_valid(element, contains) for
134-
element in instance]))
135-
)
132+
matches = sum(1 for each in instance if validator.is_valid(each, contains))
136133

137134
# default contains behavior
138135
if not matches:
@@ -144,29 +141,29 @@ def contains(validator, contains, instance, schema):
144141
if min_contains and max_contains is None:
145142
if matches < min_contains:
146143
yield ValidationError(
147-
"Invalid number or matches of %r under the given schema, "
148-
"expected min %d, got %d" % (
149-
instance, min_contains, matches
144+
"Too few matches under the given schema. "
145+
"Expected %d but there were only %d." % (
146+
min_contains, matches
150147
)
151148
)
152149
return
153150

154151
if min_contains is None and max_contains:
155152
if matches > max_contains:
156153
yield ValidationError(
157-
"Invalid number or matches of %r under the given schema, "
158-
"expected max %d, got %d" % (
159-
instance, max_contains, matches
154+
"Too many matches under the given schema. "
155+
"Expected %d but there were only %d." % (
156+
max_contains, matches
160157
)
161158
)
162159
return
163160

164161
if min_contains and max_contains:
165162
if matches < min_contains or matches > max_contains:
166163
yield ValidationError(
167-
"Invalid number or matches of %r under the given schema, "
168-
"expected min %d and max %d, got %d" % (
169-
instance, min_contains, max_contains, matches
164+
"Invalid number or matches under the given schema, "
165+
"expected between %d and %d, got %d" % (
166+
min_contains, max_contains, matches
170167
)
171168
)
172169
return
@@ -289,9 +286,6 @@ def maxLength(validator, mL, instance, schema):
289286

290287

291288
def dependentRequired(validator, dependentRequired, instance, schema):
292-
"""
293-
Split from dependencies
294-
"""
295289
if not validator.is_type(instance, "object"):
296290
return
297291

@@ -306,12 +300,6 @@ def dependentRequired(validator, dependentRequired, instance, schema):
306300

307301

308302
def dependentSchemas(validator, dependentSchemas, instance, schema):
309-
"""
310-
Split from dependencies
311-
"""
312-
if not validator.is_type(instance, "object"):
313-
return
314-
315303
for property, dependency in dependentSchemas.items():
316304
if property not in instance:
317305
continue
@@ -355,8 +343,8 @@ def dynamicRef(validator, dynamicRef, instance, schema):
355343
for url in scope_stack:
356344
lookup_url = urljoin(url, dynamicRef)
357345
with validator.resolver.resolving(lookup_url) as lookup_schema:
358-
if "$dynamicAnchor" in lookup_schema \
359-
and fragment == lookup_schema["$dynamicAnchor"]:
346+
if ("$dynamicAnchor" in lookup_schema
347+
and fragment == lookup_schema["$dynamicAnchor"]):
360348
subschema = lookup_schema
361349
for error in validator.descend(instance, subschema):
362350
yield error
@@ -375,10 +363,10 @@ def defs(validator, defs, instance, schema):
375363
if '$defs' in instance:
376364
for definition, subschema in instance['$defs'].items():
377365
for error in validator.descend(
378-
subschema,
379-
schema,
380-
path=definition,
381-
schema_path=definition,
366+
subschema,
367+
schema,
368+
path=definition,
369+
schema_path=definition,
382370
):
383371
yield error
384372

@@ -491,17 +479,14 @@ def if_(validator, if_schema, instance, schema):
491479

492480

493481
def unevaluatedItems(validator, unevaluatedItems, instance, schema):
494-
if not validator.is_type(instance, "array"):
495-
return
496-
497482
evaluated_item_indexes = find_evaluated_item_indexes_by_schema(
498483
validator, instance, schema
499484
)
500485
unevaluated_items = []
501486
for k, v in enumerate(instance):
502487
if k not in evaluated_item_indexes:
503488
for error in validator.descend(
504-
v, unevaluatedItems, schema_path="unevaluatedItems"
489+
v, unevaluatedItems, schema_path="unevaluatedItems"
505490
):
506491
unevaluated_items.append(v)
507492

@@ -511,20 +496,17 @@ def unevaluatedItems(validator, unevaluatedItems, instance, schema):
511496

512497

513498
def unevaluatedProperties(validator, unevaluatedProperties, instance, schema):
514-
if not validator.is_type(instance, "object"):
515-
return
516-
517499
evaluated_property_keys = find_evaluated_property_keys_by_schema(
518500
validator, instance, schema
519501
)
520502
unevaluated_property_keys = []
521503
for property, subschema in instance.items():
522504
if property not in evaluated_property_keys:
523505
for error in validator.descend(
524-
instance[property],
525-
unevaluatedProperties,
526-
path=property,
527-
schema_path=property,
506+
instance[property],
507+
unevaluatedProperties,
508+
path=property,
509+
schema_path=property,
528510
):
529511
unevaluated_property_keys.append(property)
530512

@@ -537,9 +519,8 @@ def prefixItems(validator, prefixItems, instance, schema):
537519
if not validator.is_type(instance, "array"):
538520
return
539521

540-
for k, v in enumerate(instance):
541-
if k < len(prefixItems):
542-
for error in validator.descend(
543-
v, prefixItems[k], schema_path="prefixItems"
544-
):
545-
yield error
522+
for k, v in enumerate(instance[:min(len(prefixItems), len(instance))]):
523+
for error in validator.descend(
524+
v, prefixItems[k], schema_path="prefixItems"
525+
):
526+
yield error

jsonschema/tests/test_format.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ def test_format_checkers_come_with_defaults(self):
7979

8080
def test_repr(self):
8181
checker = FormatChecker(formats=())
82-
checker.checks("foo")(lambda thing: True)
83-
checker.checks("bar")(lambda thing: True)
84-
checker.checks("baz")(lambda thing: True)
82+
checker.checks("foo")(lambda thing: True) # pragma: no cover
83+
checker.checks("bar")(lambda thing: True) # pragma: no cover
84+
checker.checks("baz")(lambda thing: True) # pragma: no cover
8585
self.assertEqual(
8686
repr(checker),
8787
"<FormatChecker checkers=['bar', 'baz', 'foo']>",

0 commit comments

Comments
 (0)