From 93dfd6e5d3c87853ed0c3a1963a816ce651b763e Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Thu, 19 Mar 2020 16:08:40 -0700 Subject: [PATCH 1/4] "items"/"contains"/"unevaluatedItems"/"+prefixItems/-additionalItems" This reworks the array applicators in several ways: * "prefixItems" takes on the former role of the array form of "items" * "items" keeps its single-schema role, and takes on the role of "additionalItems" when "prefixItems" is present * "contains" now produces an annotation indicating what it evaluated * "unevaluatedItems" now respects "contains", and the language around interpreting the relevant annotation is (hopefully) less convoluted Note that this does not address the change to put unevaluatedItems into a separate vocabulary with unevaluatedProperties, which will be done as a separate PR. --- jsonschema-core.xml | 108 +++++++++++++++++++------------------------ meta/applicator.json | 9 +--- 2 files changed, 49 insertions(+), 68 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index b3ab1da1..1c36d1a4 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -703,7 +703,7 @@ an alternate implementation producing the same behavior is available. Keywords of this sort SHOULD describe reasonable alternate approaches when appropriate. This approach is demonstrated by the - "" and + "" and "" keywords in this document. @@ -931,7 +931,7 @@ { "title": "Feature list", "type": "array", - "items": [ + "prefixItems": [ { "title": "Feature A", "properties": { @@ -2143,11 +2143,11 @@ "additionalProperties" and itself - "additionalItems", whose behavior is defined in terms of "items" + "items", whose behavior is defined in terms of "prefixItems" "unevaluatedItems", whose behavior is defined in terms of annotations - from "items", "additionalItems" and itself + from "prefixItems", "items", "contains", and itself @@ -2326,61 +2326,49 @@ properties and array items, and combining their results.
-
+
- The value of "items" MUST be either a valid JSON Schema or - an array of valid JSON Schemas. + The value of "prefixItems" MUST be an array of valid JSON Schemas. - If "items" is a schema, validation succeeds if all elements - in the array successfully validate against that schema. - - - If "items" is an array of schemas, validation succeeds if - each element of the instance validates against the schema at the - same position, if any. + Validation succeeds if each element of the instance validates + against the schema at the same position, if any. This keyword produces an annotation value which is the largest index to which this keyword applied a subschema. The value MAY be a boolean true if a subschema was applied to every - index of the instance, such as when "items" is a schema. - - - Annotation results for "items" keywords from multiple - schemas applied to the same instance location are combined - by setting the combined result to true if any of the values - are true, and otherwise retaining the largest numerical value. + index of the instance, such as is produced by the "items" keyword. Omitting this keyword has the same assertion behavior as - an empty schema. + an empty array.
-
- - The value of "additionalItems" MUST be a valid JSON Schema. - +
- The behavior of this keyword depends on the presence and - annotation result of "items" within the same schema object. - If "items" is present, and its annotation result is a number, - validation succeeds if every instance element at an index - greater than that number validates against "additionalItems". + The value of "items" MUST be a valid JSON Schema. - Otherwise, if "items" is absent or its annotation result - is the boolean true, "additionalItems" MUST be ignored. + This keyword applies its subschema to all instance elements + at indexes greater than the length of the "prefixItems" array + in the same schema object, as reported by the annotation result + of that "prefixItems" keyword. If no such annotation + result exists, "items" applies its subschema to all instance + array elements. + + Note that the behavior of "items" without "prefixItems" is + identical to that of the schema form of "items" in prior drafts. + When "prefixItems" is present, the behavior of "items" is + identical to the former "additionalItems" keyword. + - If the "additionalItems" subschema is applied to any + If the "items" subschema is applied to any positions within the instance array, it produces an - annotation result of boolean true, analogous to the - single schema behavior of "items". If any "additionalItems" - keyword from any subschema applied to the same instance - location produces an annotation value of true, then - the combined result from these keywords is also true. + annotation result of boolean true, indicating that all remaining array + elements have been evaluated against this keyword's subschema. Omitting this keyword has the same assertion behavior as @@ -2389,7 +2377,7 @@ Implementations MAY choose to implement or optimize this keyword in another way that produces the same effect, such as by directly - checking for the presence and size of an "items" array. + checking for the presence and size of a "prefixItems" array. Implementations that do not support annotation collection MUST do so.
@@ -2401,7 +2389,7 @@ The behavior of this keyword depends on the annotation results of adjacent keywords that apply to the instance location being validated. - Specifically, the annotations from "items" and "additionalItems", + Specifically, the annotations from "prefixItems", "items", and "contains", which can come from those keywords when they are adjacent to the "unevaluatedItems" keyword. Those two annotations, as well as "unevaluatedItems", can also result from any and all adjacent @@ -2410,33 +2398,25 @@ defined in this document. - If an "items" annotation is present, and its annotation result - is a number, and no "additionalItems" or "unevaluatedItems" - annotation is present, then validation succeeds if every instance - element at an index greater than the "items" annotation validates - against "unevaluatedItems". + If no relevant annotations are present, the "unevaluatedItems" + subschema MUST be applied to all locations in the array. + If a boolean true value is present from any of the relevant annotations, + "unevaluatedItems" MUST be ignored. Otherwise, the subschema + MUST be applied to any index greater than the largest annotation + value for "prefixItems", which does not appear in any annotation + value for "contains". - Otherwise, if any "items", "additionalItems", or "unevaluatedItems" - annotations are present with a value of boolean true, then - "unevaluatedItems" MUST be ignored. However, if none of these - annotations are present, "unevaluatedItems" MUST be applied to - all locations in the array. - - - This means that "items", "additionalItems", and all in-place applicators - MUST be evaluated before this keyword can be evaluated. Authors of - extension keywords MUST NOT define an in-place applicator that would need - to be evaluated before this keyword. + This means that "prefixItems", "items", "contains", and all in-place + applicators MUST be evaluated before this keyword can be evaluated. + Authors of extension keywords MUST NOT define an in-place applicator + that would need to be evaluated before this keyword. If the "unevaluatedItems" subschema is applied to any positions within the instance array, it produces an annotation result of boolean true, analogous to the - single schema behavior of "items". If any "unevaluatedItems" - keyword from any subschema applied to the same instance - location produces an annotation value of true, then - the combined result from these keywords is also true. + behavior of "items". Omitting this keyword has the same assertion behavior as @@ -2459,6 +2439,12 @@ array element even after the first match has been found. This is to ensure that all possible annotations are collected. + + This keyword produces an annotation value which is an array of + the indexes to which this keyword successfully applied its subschema, + in ascending order. The value MAY be a boolean true if the subschema + was successfully applied to every index of the instance. +
diff --git a/meta/applicator.json b/meta/applicator.json index a7c4a314..50052914 100644 --- a/meta/applicator.json +++ b/meta/applicator.json @@ -8,14 +8,9 @@ "title": "Applicator vocabulary meta-schema", "properties": { - "additionalItems": { "$recursiveRef": "#" }, + "prefixItems": { "$ref": "#/$defs/schemaArray" }, + "items": { "$recursiveRef": "#" }, "unevaluatedItems": { "$recursiveRef": "#" }, - "items": { - "anyOf": [ - { "$recursiveRef": "#" }, - { "$ref": "#/$defs/schemaArray" } - ] - }, "contains": { "$recursiveRef": "#" }, "additionalProperties": { "$recursiveRef": "#" }, "unevaluatedProperties": { "$recursiveRef": "#" }, From bce742bb10110d6b29b37d435ab114323bd843e7 Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Fri, 15 May 2020 11:58:11 -0700 Subject: [PATCH 2/4] Changelog for the prior commit (array applicators) This starts from the 2nd entry because a pending PR is using the first entry. --- jsonschema-core.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 1c36d1a4..7cd299a4 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -3786,9 +3786,9 @@ https://example.com/schemas/common#/$defs/count/minimum - - - + Array-value "items" functionality is now "prefixItems" + "items" subsumes the old function of "additionalItems" + "contains" and "unevaluatedItems" interactions now specified From 5cc5d1caec02d787a211f4960279415d38f09d01 Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Tue, 19 May 2020 16:15:49 -0700 Subject: [PATCH 3/4] Clarify the name "prefixItems" and its interactions --- jsonschema-core.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 7cd299a4..2739db7b 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -2332,13 +2332,17 @@ Validation succeeds if each element of the instance validates - against the schema at the same position, if any. + against the schema at the same position, if any. This keyword + does not constrain the length of the array. If the array is longer + than this keyword's value, this keyword validates only the + prefix of matching length. This keyword produces an annotation value which is the largest index to which this keyword applied a subschema. The value MAY be a boolean true if a subschema was applied to every index of the instance, such as is produced by the "items" keyword. + This annotation affects the behavior of "items" and "unevaluatedItems". Omitting this keyword has the same assertion behavior as From cfa0b72bd01bf6b1c63a12689fc6203b4caa3848 Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Thu, 28 May 2020 14:40:02 -0700 Subject: [PATCH 4/4] Update jsonschema-core.xml Co-authored-by: Ben Hutton --- jsonschema-core.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 2739db7b..d25b23ee 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -2445,9 +2445,9 @@ This keyword produces an annotation value which is an array of - the indexes to which this keyword successfully applied its subschema, - in ascending order. The value MAY be a boolean true if the subschema - was successfully applied to every index of the instance. + the indexes to which this keyword validates successfully when applying + its subschema, in ascending order. The value MAY be a boolean true if the + subschema validated successfully when applied to every index of the instance.