diff options
author | Harald Nezbeda <hn@nezhar.com> | 2021-06-17 08:50:14 +0200 |
---|---|---|
committer | Harald Nezbeda <hn@nezhar.com> | 2021-07-19 18:14:31 +0200 |
commit | 96b7fe8a2e0827d19637d6a854c5161738e284a4 (patch) | |
tree | 1c09a09fbf2d465b6bc4415c8bfa8d74d2414f07 /jsonschema/_validators.py | |
parent | 753c415866986d413a270c8a199225bdacf62ddb (diff) | |
download | jsonschema-96b7fe8a2e0827d19637d6a854c5161738e284a4.tar.gz |
Julian/jsonschema#782: Extend contains with minContains and maxContaints, add contains legacy validator
Diffstat (limited to 'jsonschema/_validators.py')
-rw-r--r-- | jsonschema/_validators.py | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/jsonschema/_validators.py b/jsonschema/_validators.py index 5a1f56a..0ca215a 100644 --- a/jsonschema/_validators.py +++ b/jsonschema/_validators.py @@ -127,10 +127,63 @@ def contains(validator, contains, instance, schema): if not validator.is_type(instance, "array"): return - if not any(validator.is_valid(element, contains) for element in instance): + min_contains = max_contains = None + + if 'minContains' in schema: + min_contains = schema['minContains'] + if not validator.is_type(min_contains, "integer"): + yield ValidationError( + "minContains of %r in not valid under the given schema" % (min_contains,) + ) + return + + if 'maxContains' in schema: + max_contains = schema['maxContains'] + if not validator.is_type(max_contains, "integer"): + yield ValidationError( + "maxContains of %r is not valid under the given schema" % (instance,) + ) + return + + # minContains set to 0 will ignore contains + if min_contains == 0: + return + + matches = len(list(filter(lambda x: x, [validator.is_valid(element, contains) for element in instance]))) + + # default contains behavior + if not matches: yield ValidationError( "None of %r are valid under the given schema" % (instance,) ) + return + + if min_contains and max_contains is None: + if matches < min_contains: + yield ValidationError( + "Invalid number or matches of %r under the given schema, expected min %d, got %d" % ( + instance, min_contains, matches + ) + ) + return + + if min_contains is None and max_contains: + if matches > max_contains: + yield ValidationError( + "Invalid number or matches of %r under the given schema, expected max %d, got %d" % ( + instance, max_contains, matches + ) + ) + return + + if min_contains and max_contains: + if matches < min_contains or matches > max_contains: + yield ValidationError( + "Invalid number or matches of %r under the given schema, expected min %d and max %d, got %d" % ( + instance, min_contains, max_contains, matches + ) + ) + return def exclusiveMinimum(validator, minimum, instance, schema): |