summaryrefslogtreecommitdiff
path: root/jsonschema/_validators.py
diff options
context:
space:
mode:
authorHarald Nezbeda <hn@nezhar.com>2021-06-17 08:50:14 +0200
committerHarald Nezbeda <hn@nezhar.com>2021-07-19 18:14:31 +0200
commit96b7fe8a2e0827d19637d6a854c5161738e284a4 (patch)
tree1c09a09fbf2d465b6bc4415c8bfa8d74d2414f07 /jsonschema/_validators.py
parent753c415866986d413a270c8a199225bdacf62ddb (diff)
downloadjsonschema-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.py55
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):