From 06849ec4f262b93177e6d6a9ca938f435d08552f Mon Sep 17 00:00:00 2001 From: Michael Sharber <112581105+micshar92@users.noreply.github.com> Date: Thu, 4 May 2023 12:25:41 -0500 Subject: [PATCH 1/9] add rough docs for unevaluatedItems --- source/reference/array.rst | 195 ++++++++++++++++++++++++++++++++++++- 1 file changed, 194 insertions(+), 1 deletion(-) diff --git a/source/reference/array.rst b/source/reference/array.rst index d4aa6a5f..1f526e47 100644 --- a/source/reference/array.rst +++ b/source/reference/array.rst @@ -236,7 +236,200 @@ Unevaluated Items |draft2019-09| -Documentation Coming Soon +The ``unevaluatedItems`` keyword selects any data types not evaluated +by an ``items``, ``prefixItems``, or `contains` keyword. Just as +unevaluated"properties" affect only "properties" in an object, only +"item"-related keywords affect unevaluated"items". + +It also applies inside valid subschemas with these keywords: +- ``allOf`` +- ``anyOf`` +- ``oneOf`` +- ``not`` +- ``if`` +- ``then`` +- ``else`` + +The main reason to use this keyword is to extend an array with extra +arguments. + +For this first example, we'll use ``unevaluatedItems`` to select any +unexpected strings. + +.. schema_example:: + + { + "items": {"type": "number"}, + "unevaluatedItems": {"type": "string"} + } + --X + // If any strings appear, then the schema doesn't validate. There are no unevaluated items in that case. + { 99, "waffles" } + -- + // But it passes so long as JSON finds all entries in an ``items``, ``prefixItems``, or ``contains``. There *are* unevaluated items in that case. + { 99, 0, 3.14159 } + +.. note:: +Watch out! The word "unevaluated" *does not* mean "not evaluated by +``items``, ``prefixItems``, or ``contains``." "Unevaluated" means +"not successfully evaluated", or "doesn't evaluate to true". + +You can also set ``unevaluatedItems`` as a boolean. + +.. schema_example:: + + { + "description": "unevaluatedItems with nested tuple", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "prefixItems": [ + { "type": "string" } + ], + "allOf": [ + { + "prefixItems": [ + true, + { "type": "number" } + ] + } + ], + "unevaluatedItems": false + }, + "tests": [ + { + "description": "with no unevaluated items", + "data": ["foo", 42], + "valid": true + }, + { + "description": "with unevaluated items", + "data": ["foo", 42, null], + "valid": false + } + ] + } + +In the first test, all the "data" items are evaluated, but in the +second test, the ``null`` value is a type not specified by +``prefixItems``. It's therefore valid and ``true`` that +``unevaluatedItems`` returns ``false`` in the first test, and invalid +and ``false`` in the second test. In other words, it is valid that no +unevaluated items exist until something not matching the string/number +pattern shows up. + +You can also select ``unevaluatedItems`` when and only when an ``if`` +statement runs. + +.. schema_example:: + + { + "description": "unevaluatedItems can see annotations from if even without then and else", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "if": { + "prefixItems": [{"const": "a"}] + }, + "unevaluatedItems": false + }, + "tests": [ + { + "description": "valid in case if is evaluated", + "data": [ "a" ], + "valid": true + }, + { + "description": "invalid in case if is evaluated", + "data": [ "b" ], + "valid": false + } + ] + } + +And an important note: ``unevaluatedItems`` can't see inside cousins +(a vertically adjacent item inside a separate pair of {curly braces} +with the same "parent"— ``anyOf``, ``if``, ``not``, or similar). Such +an instance always fails evaluation. + +.. schema_example:: + + { + "description": "unevaluatedItems can't see inside cousins", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "allOf": [ + { + "prefixItems": [ true ] + }, + { "unevaluatedItems": false } + ] + }, + "tests": [ + { + "description": "always fails", + "data": [ 1 ], + "valid": false + } + ] + } + +Finally, here's an example of ``unevaluatedItems`` if you're +`structuring`. Let's make a "half-closed" schema: something useful +when you want to keep the first two arguments, but also add more in +certain situations. ("Closed" to two in some places, "open" to more +in others.) + +.. schema_example:: + + { + "$id": "https://example.com/my-tuple", + + "type": "array", + "prefixItems": [ + true, + { "type": "boolean" } + ], + + "$defs": { + "closed": { + "$anchor": "closed", + "$ref": "#", + "unevaluatedItems": false + } + } + } + +Then we can extend the tuple: + +.. schema_example:: + + { + "$id": "https://example.com/my-extended-tuple", + + "$ref": "/my-tuple", + "prefixItems": [ + true, + true, + { "type": "boolean" } + ], + "unevaluatedItems": false + } + +With this, you can use ``$ref`` to reference the first two +``prefixItems`` and keep the schema "closed" to two when necessary, +"open" to more when necessary. A reference to ``/my-tuple#closed`` +would disallow more than two items, when you need it to. + +.. note:: + For a tower of more examples, read our `unevaluatedItems Test Suite `_ on GitHub. + We test a lot of use cases there, including uncommon ones. Do any + of these apply to your schema? + - using ``unevaluatedItems`` as a schema + - ``unevaluatedItems`` nested inside another ``unevaluatedItems`` + - ``if/then/else`` statements with ``unevaluatedItems`` + - multiples nested ``if``/``then``s + - multiple nested instances of ``contains`` + - ignoring non-array types + - ``not`` .. index:: single: array; contains From 1561111963995451bde51d266311a59b1920cb10 Mon Sep 17 00:00:00 2001 From: Michael Sharber <112581105+micshar92@users.noreply.github.com> Date: Thu, 25 May 2023 13:45:07 -0500 Subject: [PATCH 2/9] unevaluatedItems rough 2 second draft of ``unevaluatedItems`` tutorial --- source/reference/array.rst | 233 +++++++++++++++++++------------------ 1 file changed, 121 insertions(+), 112 deletions(-) diff --git a/source/reference/array.rst b/source/reference/array.rst index 1f526e47..c2729e11 100644 --- a/source/reference/array.rst +++ b/source/reference/array.rst @@ -236,52 +236,136 @@ Unevaluated Items |draft2019-09| -The ``unevaluatedItems`` keyword selects any data types not evaluated +The ``unevaluatedItems`` keyword applies to any values not evaluated by an ``items``, ``prefixItems``, or `contains` keyword. Just as -unevaluated"properties" affect only "properties" in an object, only -"item"-related keywords affect unevaluated"items". +unevaluated**properties** affect only **properties** in an object, only +**item**-related keywords affect unevaluated**items**. -It also applies inside valid subschemas with these keywords: -- ``allOf`` -- ``anyOf`` -- ``oneOf`` -- ``not`` -- ``if`` -- ``then`` -- ``else`` +.. note:: +Watch out! The word "unevaluated" *does not* mean "not evaluated by +``items``, ``prefixItems``, or ``contains``." "Unevaluated" means +"not successfully evaluated", or "doesn't evaluate to true". + +For this first example, let's assume you want to allow lists of items +that begin with either "1" or "A," but anything after must be 2. + +..schema_example:: + +{ + "oneOf": [{"prefixItems": [{"const": 1}]}, {"prefixItems": [{"const": "a"}]}], + "items": {"const": 2}, +} + +The logic here seems like it should be "one of either 1 or A and then 2." +Actually, it's "either 1 or A **or 2** and also 2." So anything that's +not a 2 fails validation. That's because ``allOf``, ``anyOf``, and ``oneOf`` +attach themselves to ``items`` in the same subschema. + +But if you replace ``items`` with ``unevaluatedItems``, it passes. +Anything that starts with "1" or "A" and then continues with a "2" is +valid in that case. ``allOf``, ``anyOf``, and ``oneOf`` do not attach +themselves to ``unevaluatedItems``. + +You can also define ``unevaluatedItems`` as a boolean. In the next +example, let's use ``unevaluatedItems`` to make sure we have no values +outside of "SKU" and "product." + +..schema_example:: + + { + "allOf": [ + { + "type": "array", + "items": { + "SKU": "number", + "product": "string", + }, + "unevaluatedItems": false + } + ], + + "items": { + "quantity": { "enum": ["1", "2", "3"] } + }, + "required": ["quantity"], + } + +This schema will always fail validation because "quantity" is required, +but it's outside of the ``allOf``, and ``unevaluatedItems`` *does not recognize any values outside of its own subschema*. +Here, ``unevaluatedItems`` considers anything outside of "SKU" and +"product" to be additional. Combining the schemas with ``allOf`` won’t +change that. + +Instead, keep all your ``unevaluatedItems`` in the same list: + +..schema_example:: -The main reason to use this keyword is to extend an array with extra -arguments. + { + "items": { + "SKU": "number", + "product": "string", + "quantity": { "enum": ["1", "2", "3"] } + }, + "required": ["quantity"], + "unevaluatedItems": false + } -For this first example, we'll use ``unevaluatedItems`` to select any -unexpected strings. +Similarly, you can use ``unevaluatedItems`` if you're `structuring`. +Let's make a "half-closed" schema: something useful when you want to +keep the first two arguments, but also add more in certain situations. +("Closed" to two arguments in some places, "open" to more arguments +when you need it to be.) .. schema_example:: { - "items": {"type": "number"}, - "unevaluatedItems": {"type": "string"} + "$id": "https://example.com/my-tuple", + + "type": "array", + "prefixItems": [ + true, + { "type": "boolean" } + ], + + "$defs": { + "closed": { + "$anchor": "closed", + "$ref": "#", + "unevaluatedItems": false + } + } } - --X - // If any strings appear, then the schema doesn't validate. There are no unevaluated items in that case. - { 99, "waffles" } - -- - // But it passes so long as JSON finds all entries in an ``items``, ``prefixItems``, or ``contains``. There *are* unevaluated items in that case. - { 99, 0, 3.14159 } -.. note:: -Watch out! The word "unevaluated" *does not* mean "not evaluated by -``items``, ``prefixItems``, or ``contains``." "Unevaluated" means -"not successfully evaluated", or "doesn't evaluate to true". +Then we can extend the tuple with another value: + +.. schema_example:: + + { + "$id": "https://example.com/my-extended-tuple", -You can also set ``unevaluatedItems`` as a boolean. + "$ref": "https://example.com/my-tuple", + "prefixItems": [ + true, + true, + { "type": "boolean" } + ], + "unevaluatedItems": false + } + +With this, you can use ``$ref`` to reference the first two +``prefixItems`` and keep the schema "closed" to two arguments when +you need it, "open" to more arguments when you need it. A reference to +``/my-tuple#closed`` would disallow more than two items. +``unevaluatedItems`` only reads inside the subschema it's attached to, +so if you want to add an item, add it inside that subschema. + +You can also set ``unevaluatedItems`` in a nested tuple. .. schema_example:: { "description": "unevaluatedItems with nested tuple", "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", "prefixItems": [ { "type": "string" } ], @@ -309,7 +393,7 @@ You can also set ``unevaluatedItems`` as a boolean. ] } -In the first test, all the "data" items are evaluated, but in the +In the first test, all the "data" values are evaluated, but in the second test, the ``null`` value is a type not specified by ``prefixItems``. It's therefore valid and ``true`` that ``unevaluatedItems`` returns ``false`` in the first test, and invalid @@ -317,38 +401,10 @@ and ``false`` in the second test. In other words, it is valid that no unevaluated items exist until something not matching the string/number pattern shows up. -You can also select ``unevaluatedItems`` when and only when an ``if`` -statement runs. - -.. schema_example:: - - { - "description": "unevaluatedItems can see annotations from if even without then and else", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "if": { - "prefixItems": [{"const": "a"}] - }, - "unevaluatedItems": false - }, - "tests": [ - { - "description": "valid in case if is evaluated", - "data": [ "a" ], - "valid": true - }, - { - "description": "invalid in case if is evaluated", - "data": [ "b" ], - "valid": false - } - ] - } - -And an important note: ``unevaluatedItems`` can't see inside cousins -(a vertically adjacent item inside a separate pair of {curly braces} -with the same "parent"— ``anyOf``, ``if``, ``not``, or similar). Such -an instance always fails evaluation. +Lastly, here's an important note: ``unevaluatedItems`` can't see inside +cousins (a vertically adjacent item inside a separate pair of {curly +braces} with the same "parent"— ``anyOf``, ``if``, ``not``, or similar). +Such an instance always fails validation. .. schema_example:: @@ -356,7 +412,7 @@ an instance always fails evaluation. "description": "unevaluatedItems can't see inside cousins", "schema": { "$schema": "https://json-schema.org/draft/2020-12/schema", - "allOf": [ + "oneOf": [ { "prefixItems": [ true ] }, @@ -372,64 +428,17 @@ an instance always fails evaluation. ] } -Finally, here's an example of ``unevaluatedItems`` if you're -`structuring`. Let's make a "half-closed" schema: something useful -when you want to keep the first two arguments, but also add more in -certain situations. ("Closed" to two in some places, "open" to more -in others.) - -.. schema_example:: - - { - "$id": "https://example.com/my-tuple", - - "type": "array", - "prefixItems": [ - true, - { "type": "boolean" } - ], - - "$defs": { - "closed": { - "$anchor": "closed", - "$ref": "#", - "unevaluatedItems": false - } - } - } - -Then we can extend the tuple: - -.. schema_example:: - - { - "$id": "https://example.com/my-extended-tuple", - - "$ref": "/my-tuple", - "prefixItems": [ - true, - true, - { "type": "boolean" } - ], - "unevaluatedItems": false - } - -With this, you can use ``$ref`` to reference the first two -``prefixItems`` and keep the schema "closed" to two when necessary, -"open" to more when necessary. A reference to ``/my-tuple#closed`` -would disallow more than two items, when you need it to. - .. note:: - For a tower of more examples, read our `unevaluatedItems Test Suite `_ on GitHub. + For a tall list of more examples, read our `unevaluatedItems Test Suite `_ on GitHub. We test a lot of use cases there, including uncommon ones. Do any of these apply to your schema? - - using ``unevaluatedItems`` as a schema - ``unevaluatedItems`` nested inside another ``unevaluatedItems`` - ``if/then/else`` statements with ``unevaluatedItems`` - multiples nested ``if``/``then``s - multiple nested instances of ``contains`` - ignoring non-array types - ``not`` + - and more .. index:: single: array; contains From fa9a9c55dda7bdb244d0ebf5e460323dc04b5046 Mon Sep 17 00:00:00 2001 From: Michael Sharber <112581105+micshar92@users.noreply.github.com> Date: Sat, 27 May 2023 11:09:42 -0500 Subject: [PATCH 3/9] ``unevaluatedItems`` next-to-final draft third draft of ``unevaluatedItems`` tutorial --- source/reference/array.rst | 137 ++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 70 deletions(-) diff --git a/source/reference/array.rst b/source/reference/array.rst index c2729e11..7935a3a9 100644 --- a/source/reference/array.rst +++ b/source/reference/array.rst @@ -238,16 +238,11 @@ Unevaluated Items The ``unevaluatedItems`` keyword applies to any values not evaluated by an ``items``, ``prefixItems``, or `contains` keyword. Just as -unevaluated**properties** affect only **properties** in an object, only -**item**-related keywords affect unevaluated**items**. - -.. note:: -Watch out! The word "unevaluated" *does not* mean "not evaluated by -``items``, ``prefixItems``, or ``contains``." "Unevaluated" means -"not successfully evaluated", or "doesn't evaluate to true". +``unevaluatedProperties`` affects only **properties** in an object, +``unevaluatedItems`` affects only **item**-related keywords. For this first example, let's assume you want to allow lists of items -that begin with either "1" or "A," but anything after must be 2. +that begin with either ``1`` or ``"A"``, but anything after must be ``2``. ..schema_example:: @@ -256,19 +251,25 @@ that begin with either "1" or "A," but anything after must be 2. "items": {"const": 2}, } -The logic here seems like it should be "one of either 1 or A and then 2." -Actually, it's "either 1 or A **or 2** and also 2." So anything that's -not a 2 fails validation. That's because ``allOf``, ``anyOf``, and ``oneOf`` -attach themselves to ``items`` in the same subschema. +The logic here seems like it should be "one of either ``1`` or ``"A"`` +and then ``2``." Actually, it's "either ``1`` or ``"A"`` *and also* ``2``." +And ``items`` expects a ``2`` here, so anything that's not a ``2`` +fails validation. That's because ``items`` doesn't "see inside" any +instances of ``oneOf``, ``anyOf``, or ``allOf`` in the same subschema. But if you replace ``items`` with ``unevaluatedItems``, it passes. -Anything that starts with "1" or "A" and then continues with a "2" is -valid in that case. ``allOf``, ``anyOf``, and ``oneOf`` do not attach -themselves to ``unevaluatedItems``. +Anything that starts with ``1`` or ``A`` and then continues with a ``2`` +is valid in that case. + +Because booleans are valid schemas for any JSON Schema keyword, you can +also prevent additional items by setting ``unevaluatedItems`` to +``false.`` In the next example, let's use ``unevaluatedItems`` to make +sure we allow no properties besides ``SKU`` and ``product``. -You can also define ``unevaluatedItems`` as a boolean. In the next -example, let's use ``unevaluatedItems`` to make sure we have no values -outside of "SKU" and "product." +.. note:: +Watch out! The word "unevaluated" *does not* mean "not evaluated by +``items``, ``prefixItems``, or ``contains``." "Unevaluated" means +"not successfully evaluated", or "doesn't evaluate to true". ..schema_example:: @@ -287,16 +288,16 @@ outside of "SKU" and "product." "items": { "quantity": { "enum": ["1", "2", "3"] } }, - "required": ["quantity"], + "required": ["quantity"], } -This schema will always fail validation because "quantity" is required, -but it's outside of the ``allOf``, and ``unevaluatedItems`` *does not recognize any values outside of its own subschema*. -Here, ``unevaluatedItems`` considers anything outside of "SKU" and -"product" to be additional. Combining the schemas with ``allOf`` won’t -change that. +This schema will always fail validation because ``quantity`` is required +but it's outside the ``allOf``, and ``unevaluatedItems`` +*does not see any items outside its own subschema*. Here, +``unevaluatedItems`` considers anything outside of ``SKU`` and ``product`` +to be additional. -Instead, keep all your ``unevaluatedItems`` in the same list: +Instead, keep all your ``unevaluatedItems`` in the same subschema: ..schema_example:: @@ -310,7 +311,36 @@ Instead, keep all your ``unevaluatedItems`` in the same list: "unevaluatedItems": false } -Similarly, you can use ``unevaluatedItems`` if you're `structuring`. +Similarly, ``unevaluatedItems`` can't see inside cousins (vertically +adjacent properties inside a separate pair of {curly braces} with the +same "parent"— ``anyOf``, ``if``, ``not``, or similar). For instance, +in the example below, the ``unevaluatedItems`` doesn't "see inside" the +``prefixItems`` cousin before it. So since ``"prefixItems": [ true ]`` +matches only length 1 arrays, and ``{ "unevaluatedItems": false }`` +matches only empty arrays, all instances fail validation. + +.. schema_example:: + + { + "schema": { + "oneOf": [ + { + "prefixItems": [ true ] + }, + { "unevaluatedItems": false } + ] + }, + "tests": [ + { + "description": "always fails", + "data": [ 1 ], + "valid": false + } + ] + } + + +You can also use ``unevaluatedItems`` when you're `structuring`. Let's make a "half-closed" schema: something useful when you want to keep the first two arguments, but also add more in certain situations. ("Closed" to two arguments in some places, "open" to more arguments @@ -356,15 +386,14 @@ With this, you can use ``$ref`` to reference the first two ``prefixItems`` and keep the schema "closed" to two arguments when you need it, "open" to more arguments when you need it. A reference to ``/my-tuple#closed`` would disallow more than two items. -``unevaluatedItems`` only reads inside the subschema it's attached to, -so if you want to add an item, add it inside that subschema. +``unevaluatedItems`` only sees inside its own subschema, so if you +want to add an item, add it inside that subschema. -You can also set ``unevaluatedItems`` in a nested tuple. +This means you can also put ``unevaluatedItems`` in a nested tuple. .. schema_example:: { - "description": "unevaluatedItems with nested tuple", "schema": { "prefixItems": [ { "type": "string" } @@ -386,58 +415,26 @@ You can also set ``unevaluatedItems`` in a nested tuple. "valid": true }, { - "description": "with unevaluated items", + "description": "with an unevaluated item", "data": ["foo", 42, null], "valid": false } ] } -In the first test, all the "data" values are evaluated, but in the -second test, the ``null`` value is a type not specified by -``prefixItems``. It's therefore valid and ``true`` that -``unevaluatedItems`` returns ``false`` in the first test, and invalid -and ``false`` in the second test. In other words, it is valid that no -unevaluated items exist until something not matching the string/number -pattern shows up. - -Lastly, here's an important note: ``unevaluatedItems`` can't see inside -cousins (a vertically adjacent item inside a separate pair of {curly -braces} with the same "parent"— ``anyOf``, ``if``, ``not``, or similar). -Such an instance always fails validation. - -.. schema_example:: - - { - "description": "unevaluatedItems can't see inside cousins", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "oneOf": [ - { - "prefixItems": [ true ] - }, - { "unevaluatedItems": false } - ] - }, - "tests": [ - { - "description": "always fails", - "data": [ 1 ], - "valid": false - } - ] - } +In the first test, all the ``data`` values are evaluated, but in the +second test, a third value exists. ``prefixItems`` contrains only two +items, and ``unevaluatedItems`` applies only to those two. .. note:: For a tall list of more examples, read our `unevaluatedItems Test Suite `_ on GitHub. We test a lot of use cases there, including uncommon ones. Do any of these apply to your schema? - ``unevaluatedItems`` nested inside another ``unevaluatedItems`` - - ``if/then/else`` statements with ``unevaluatedItems`` - - multiples nested ``if``/``then``s - - multiple nested instances of ``contains`` - - ignoring non-array types - - ``not`` + - ``if/then/else`` statements interacting with ``unevaluatedItems`` + - nested ``if/then/else`` statements interacting with ``unevaluatedItems`` + - ``unevaluatedItems`` ignoring non-arrays + - ``unevaluatedItems`` interacting with the ``not`` keyword - and more .. index:: From 7c808fadfdfdf9ec1c995b1f4dabff9ad2bf75a2 Mon Sep 17 00:00:00 2001 From: Michael Sharber <112581105+micshar92@users.noreply.github.com> Date: Tue, 30 May 2023 12:30:54 -0500 Subject: [PATCH 4/9] ``unevaluatedItems`` fourth draft fourth draft of ``unevaluatedItems`` tutorial --- source/reference/array.rst | 112 ++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 63 deletions(-) diff --git a/source/reference/array.rst b/source/reference/array.rst index 7935a3a9..96f1d864 100644 --- a/source/reference/array.rst +++ b/source/reference/array.rst @@ -237,19 +237,19 @@ Unevaluated Items |draft2019-09| The ``unevaluatedItems`` keyword applies to any values not evaluated -by an ``items``, ``prefixItems``, or `contains` keyword. Just as +by an ``items``, ``prefixItems``, or ``contains`` keyword. Just as ``unevaluatedProperties`` affects only **properties** in an object, ``unevaluatedItems`` affects only **item**-related keywords. For this first example, let's assume you want to allow lists of items that begin with either ``1`` or ``"A"``, but anything after must be ``2``. -..schema_example:: +.. schema_example:: -{ - "oneOf": [{"prefixItems": [{"const": 1}]}, {"prefixItems": [{"const": "a"}]}], - "items": {"const": 2}, -} + { + "oneOf": [{"prefixItems": [{"const": 1}]}, {"prefixItems": [{"const": "a"}]}], + "items": {"const": 2}, + } The logic here seems like it should be "one of either ``1`` or ``"A"`` and then ``2``." Actually, it's "either ``1`` or ``"A"`` *and also* ``2``." @@ -267,28 +267,32 @@ also prevent additional items by setting ``unevaluatedItems`` to sure we allow no properties besides ``SKU`` and ``product``. .. note:: -Watch out! The word "unevaluated" *does not* mean "not evaluated by -``items``, ``prefixItems``, or ``contains``." "Unevaluated" means -"not successfully evaluated", or "doesn't evaluate to true". + Watch out! The word "unevaluated" *does not* mean "not evaluated by + ``items``, ``prefixItems``, or ``contains``." "Unevaluated" means + "not successfully evaluated", or "doesn't evaluate to true". -..schema_example:: +.. schema_example:: { "allOf": [ { "type": "array", "items": { - "SKU": "number", - "product": "string", + "properties": { + "SKU": "number", + "product": "string" + } }, "unevaluatedItems": false } ], "items": { - "quantity": { "enum": ["1", "2", "3"] } - }, - "required": ["quantity"], + "properties": { + "quantity": { "enum": ["1", "2", "3"] } + }, + "required": ["quantity"] + } } This schema will always fail validation because ``quantity`` is required @@ -299,16 +303,18 @@ to be additional. Instead, keep all your ``unevaluatedItems`` in the same subschema: -..schema_example:: +.. schema_example:: { "items": { - "SKU": "number", - "product": "string", - "quantity": { "enum": ["1", "2", "3"] } + "properties": { + "SKU": "number", + "product": "string", + "quantity": { "enum": ["1", "2", "3"] } + } + "required": ["quantity"] }, - "required": ["quantity"], - "unevaluatedItems": false + "unevaluatedItems": false } Similarly, ``unevaluatedItems`` can't see inside cousins (vertically @@ -322,23 +328,13 @@ matches only empty arrays, all instances fail validation. .. schema_example:: { - "schema": { - "oneOf": [ - { - "prefixItems": [ true ] - }, - { "unevaluatedItems": false } - ] - }, - "tests": [ - { - "description": "always fails", - "data": [ 1 ], - "valid": false - } - ] + "oneOf": [ + { "prefixItems": [true] }, + { "unevaluatedItems": false } + ] } - + --X + [1] You can also use ``unevaluatedItems`` when you're `structuring`. Let's make a "half-closed" schema: something useful when you want to @@ -394,33 +390,23 @@ This means you can also put ``unevaluatedItems`` in a nested tuple. .. schema_example:: { - "schema": { - "prefixItems": [ - { "type": "string" } - ], - "allOf": [ - { - "prefixItems": [ - true, - { "type": "number" } - ] - } - ], - "unevaluatedItems": false - }, - "tests": [ - { - "description": "with no unevaluated items", - "data": ["foo", 42], - "valid": true - }, - { - "description": "with an unevaluated item", - "data": ["foo", 42, null], - "valid": false - } - ] + "prefixItems": [ + { "type": "string" } + ], + "allOf": [ + { + "prefixItems": [ + true, + { "type": "number" } + ] + } + ], + "unevaluatedItems": false } + -- + ["foo", 42] + --X + ["foo", 42, null] In the first test, all the ``data`` values are evaluated, but in the second test, a third value exists. ``prefixItems`` contrains only two From 05c48d63c0f9207961a383eee650afdea5667ead Mon Sep 17 00:00:00 2001 From: Michael Sharber <112581105+micshar92@users.noreply.github.com> Date: Tue, 6 Jun 2023 16:46:20 -0500 Subject: [PATCH 5/9] Fifth draft of ``unevaluatedItems`` tutorial --- source/reference/array.rst | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/source/reference/array.rst b/source/reference/array.rst index 96f1d864..8ad33d19 100644 --- a/source/reference/array.rst +++ b/source/reference/array.rst @@ -248,7 +248,7 @@ that begin with either ``1`` or ``"A"``, but anything after must be ``2``. { "oneOf": [{"prefixItems": [{"const": 1}]}, {"prefixItems": [{"const": "a"}]}], - "items": {"const": 2}, + "items": {"const": 2} } The logic here seems like it should be "one of either ``1`` or ``"A"`` @@ -311,7 +311,7 @@ Instead, keep all your ``unevaluatedItems`` in the same subschema: "SKU": "number", "product": "string", "quantity": { "enum": ["1", "2", "3"] } - } + }, "required": ["quantity"] }, "unevaluatedItems": false @@ -320,15 +320,15 @@ Instead, keep all your ``unevaluatedItems`` in the same subschema: Similarly, ``unevaluatedItems`` can't see inside cousins (vertically adjacent properties inside a separate pair of {curly braces} with the same "parent"— ``anyOf``, ``if``, ``not``, or similar). For instance, -in the example below, the ``unevaluatedItems`` doesn't "see inside" the -``prefixItems`` cousin before it. So since ``"prefixItems": [ true ]`` -matches only length 1 arrays, and ``{ "unevaluatedItems": false }`` -matches only empty arrays, all instances fail validation. +in the example below, the ``unevaluatedItems`` doesn't "see inside" +the ``prefixItems`` cousin before it. All instances fail vallidation +because ``"prefixItems": [ true ]`` matches only length 1 arrays, and +``{ "unevaluatedItems": false }`` matches only empty arrays. .. schema_example:: { - "oneOf": [ + "allOf": [ { "prefixItems": [true] }, { "unevaluatedItems": false } ] @@ -413,15 +413,16 @@ second test, a third value exists. ``prefixItems`` contrains only two items, and ``unevaluatedItems`` applies only to those two. .. note:: - For a tall list of more examples, read our `unevaluatedItems Test Suite `_ on GitHub. - We test a lot of use cases there, including uncommon ones. Do any - of these apply to your schema? - - ``unevaluatedItems`` nested inside another ``unevaluatedItems`` - - ``if/then/else`` statements interacting with ``unevaluatedItems`` - - nested ``if/then/else`` statements interacting with ``unevaluatedItems`` - - ``unevaluatedItems`` ignoring non-arrays - - ``unevaluatedItems`` interacting with the ``not`` keyword - - and more + For a tall list of more examples, read our `unevaluatedItems Test Suite `_ on GitHub. We test a lot of use cases + there, including uncommon ones. + +Here are some of our examples in the suite: + * ``unevaluatedItems`` nested inside another ``unevaluatedItems`` + * ``if/then/else`` statements interacting with ``unevaluatedItems`` + * nested ``if/then/else`` statements interacting with ``unevaluatedItems`` + * ``unevaluatedItems`` ignoring non-arrays + * ``unevaluatedItems`` interacting with the ``not`` keyword + * and more .. index:: single: array; contains From b154f7b20dbe9ea3a64998573ea757b83d2412cb Mon Sep 17 00:00:00 2001 From: Michael Sharber <112581105+micshar92@users.noreply.github.com> Date: Mon, 12 Jun 2023 11:52:56 -0500 Subject: [PATCH 6/9] Sixth draft of ``unevaluatedItems`` tutorial --- source/reference/array.rst | 153 ++++++++++++------------------------- 1 file changed, 48 insertions(+), 105 deletions(-) diff --git a/source/reference/array.rst b/source/reference/array.rst index 8ad33d19..d927b4a3 100644 --- a/source/reference/array.rst +++ b/source/reference/array.rst @@ -239,108 +239,17 @@ Unevaluated Items The ``unevaluatedItems`` keyword applies to any values not evaluated by an ``items``, ``prefixItems``, or ``contains`` keyword. Just as ``unevaluatedProperties`` affects only **properties** in an object, -``unevaluatedItems`` affects only **item**-related keywords. - -For this first example, let's assume you want to allow lists of items -that begin with either ``1`` or ``"A"``, but anything after must be ``2``. - -.. schema_example:: - - { - "oneOf": [{"prefixItems": [{"const": 1}]}, {"prefixItems": [{"const": "a"}]}], - "items": {"const": 2} - } - -The logic here seems like it should be "one of either ``1`` or ``"A"`` -and then ``2``." Actually, it's "either ``1`` or ``"A"`` *and also* ``2``." -And ``items`` expects a ``2`` here, so anything that's not a ``2`` -fails validation. That's because ``items`` doesn't "see inside" any -instances of ``oneOf``, ``anyOf``, or ``allOf`` in the same subschema. - -But if you replace ``items`` with ``unevaluatedItems``, it passes. -Anything that starts with ``1`` or ``A`` and then continues with a ``2`` -is valid in that case. - -Because booleans are valid schemas for any JSON Schema keyword, you can -also prevent additional items by setting ``unevaluatedItems`` to -``false.`` In the next example, let's use ``unevaluatedItems`` to make -sure we allow no properties besides ``SKU`` and ``product``. +``unevaluatedItems`` affects only **items** in an array. .. note:: Watch out! The word "unevaluated" *does not* mean "not evaluated by ``items``, ``prefixItems``, or ``contains``." "Unevaluated" means "not successfully evaluated", or "doesn't evaluate to true". -.. schema_example:: - - { - "allOf": [ - { - "type": "array", - "items": { - "properties": { - "SKU": "number", - "product": "string" - } - }, - "unevaluatedItems": false - } - ], - - "items": { - "properties": { - "quantity": { "enum": ["1", "2", "3"] } - }, - "required": ["quantity"] - } - } - -This schema will always fail validation because ``quantity`` is required -but it's outside the ``allOf``, and ``unevaluatedItems`` -*does not see any items outside its own subschema*. Here, -``unevaluatedItems`` considers anything outside of ``SKU`` and ``product`` -to be additional. - -Instead, keep all your ``unevaluatedItems`` in the same subschema: - -.. schema_example:: - - { - "items": { - "properties": { - "SKU": "number", - "product": "string", - "quantity": { "enum": ["1", "2", "3"] } - }, - "required": ["quantity"] - }, - "unevaluatedItems": false - } - -Similarly, ``unevaluatedItems`` can't see inside cousins (vertically -adjacent properties inside a separate pair of {curly braces} with the -same "parent"— ``anyOf``, ``if``, ``not``, or similar). For instance, -in the example below, the ``unevaluatedItems`` doesn't "see inside" -the ``prefixItems`` cousin before it. All instances fail vallidation -because ``"prefixItems": [ true ]`` matches only length 1 arrays, and -``{ "unevaluatedItems": false }`` matches only empty arrays. - -.. schema_example:: - - { - "allOf": [ - { "prefixItems": [true] }, - { "unevaluatedItems": false } - ] - } - --X - [1] - -You can also use ``unevaluatedItems`` when you're `structuring`. -Let's make a "half-closed" schema: something useful when you want to -keep the first two arguments, but also add more in certain situations. -("Closed" to two arguments in some places, "open" to more arguments -when you need it to be.) +For this first example, let's make a "half-closed" schema: something +useful when you want to keep the first two arguments, but also add +more in certain situations. ("Closed" to two arguments in some +places, "open" to more arguments when you need it to be.) .. schema_example:: @@ -348,7 +257,7 @@ when you need it to be.) "$id": "https://example.com/my-tuple", "type": "array", - "prefixItems": [ + "items": [ true, { "type": "boolean" } ], @@ -356,13 +265,15 @@ when you need it to be.) "$defs": { "closed": { "$anchor": "closed", - "$ref": "#", - "unevaluatedItems": false + "$ref": "#" } } } -Then we can extend the tuple with another value: +``items`` evaluates only the items in the initial array. Any items +you add when you extend the tuple later *are not evaluated*. When +you extend the tuple, the schema passes validation only if you include +``unevaluatedItems`` like this: .. schema_example:: @@ -381,8 +292,8 @@ Then we can extend the tuple with another value: With this, you can use ``$ref`` to reference the first two ``prefixItems`` and keep the schema "closed" to two arguments when you need it, "open" to more arguments when you need it. A reference to -``/my-tuple#closed`` would disallow more than two items. -``unevaluatedItems`` only sees inside its own subschema, so if you +``/my-tuple#closed`` would disallow more than two items. And because +``unevaluatedItems`` only sees inside its own subschema, if you want to add an item, add it inside that subschema. This means you can also put ``unevaluatedItems`` in a nested tuple. @@ -405,12 +316,44 @@ This means you can also put ``unevaluatedItems`` in a nested tuple. } -- ["foo", 42] + // All the array items are evaluated. The schema passes validation. --X ["foo", 42, null] + // The third value is unevaluated, so ``unevaluatedItems`` is true, + // not false. The schema fails validation. + +Note these two restraints, though. First, ``items`` doesn't "see +inside" any instances of ``allOf``, ``anyOf``, or ``oneOf`` in the +same subschema. In this next example, ``items`` ignores ``allOf`` and +thus fails to validate. + +.. schema_example:: + + { + "allOf": [{ "prefixItems": [{ "enum": [1, "a"] }] }], + "items": { "const": 2 } + } + --X + [1, "a", 2] + +Second, ``unevaluatedItems`` can't "see inside" cousins (vertically +adjacent properties inside a separate pair of {curly braces} with the +same "parent"— ``anyOf``, ``if``, ``not``, or similar). For instance, +in the example below, the ``unevaluatedItems`` doesn't "see inside" +the ``prefixItems`` cousin before it. All instances fail validation +because ``"prefixItems": [ true ]`` matches only length 1 arrays, and +``{ "unevaluatedItems": false }`` matches only empty arrays. + +.. schema_example:: -In the first test, all the ``data`` values are evaluated, but in the -second test, a third value exists. ``prefixItems`` contrains only two -items, and ``unevaluatedItems`` applies only to those two. + { + "allOf": [ + { "prefixItems": [true] }, + { "unevaluatedItems": false } + ] + } + --X + [1] .. note:: For a tall list of more examples, read our `unevaluatedItems Test Suite `_ on GitHub. We test a lot of use cases From 6e434e06c84460d74f591a14cc415d530a00cd60 Mon Sep 17 00:00:00 2001 From: Michael Sharber <112581105+micshar92@users.noreply.github.com> Date: Wed, 14 Jun 2023 15:34:45 -0500 Subject: [PATCH 7/9] ``unevaluatedItems`` tutorial seventh draft Seventh draft. Much simplified. After I removed the reference to the test suite at the end, I toyed with adding some conclusion sentence-- it seems abrupt-- but it was just fluff, so I didn't. Anyway, here it is. --- source/reference/array.rst | 145 ++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 84 deletions(-) diff --git a/source/reference/array.rst b/source/reference/array.rst index d927b4a3..ed4ba21e 100644 --- a/source/reference/array.rst +++ b/source/reference/array.rst @@ -242,130 +242,107 @@ by an ``items``, ``prefixItems``, or ``contains`` keyword. Just as ``unevaluatedItems`` affects only **items** in an array. .. note:: - Watch out! The word "unevaluated" *does not* mean "not evaluated by + Watch out! The word "unevaluated" *does not mean* "not evaluated by ``items``, ``prefixItems``, or ``contains``." "Unevaluated" means "not successfully evaluated", or "doesn't evaluate to true". -For this first example, let's make a "half-closed" schema: something -useful when you want to keep the first two arguments, but also add -more in certain situations. ("Closed" to two arguments in some -places, "open" to more arguments when you need it to be.) +``items`` doesn't "see inside" any instances of ``allOf``, ``anyOf``, +or ``oneOf`` in the same subschema. In this first example, ``items`` +ignores ``allOf`` and thus fails to validate. .. schema_example:: { - "$id": "https://example.com/my-tuple", - - "type": "array", - "items": [ - true, - { "type": "boolean" } - ], - - "$defs": { - "closed": { - "$anchor": "closed", - "$ref": "#" - } - } + "allOf": [{ "prefixItems": [{ "type": "boolean" }, { "type": "string" }] }], + "items": { "const": 2 } } + --X + [true, "a", 2] -``items`` evaluates only the items in the initial array. Any items -you add when you extend the tuple later *are not evaluated*. When -you extend the tuple, the schema passes validation only if you include -``unevaluatedItems`` like this: +But if you replace ``items`` with ``unevaluatedItems``, then the same +array validates. .. schema_example:: { - "$id": "https://example.com/my-extended-tuple", - - "$ref": "https://example.com/my-tuple", - "prefixItems": [ - true, - true, - { "type": "boolean" } - ], - "unevaluatedItems": false + "allOf": [{ "prefixItems": [{ "type": "boolean" }, { "type": "string" }] }], + "unevaluatedItems": { "const": 2 } } + -- + [true, "a", 2] -With this, you can use ``$ref`` to reference the first two -``prefixItems`` and keep the schema "closed" to two arguments when -you need it, "open" to more arguments when you need it. A reference to -``/my-tuple#closed`` would disallow more than two items. And because -``unevaluatedItems`` only sees inside its own subschema, if you -want to add an item, add it inside that subschema. - -This means you can also put ``unevaluatedItems`` in a nested tuple. +Like with ``items``, if you set ``unevaluatedItems`` to ``false``, you +can disallow extra items in the array. .. schema_example:: { "prefixItems": [ - { "type": "string" } - ], - "allOf": [ - { - "prefixItems": [ - true, - { "type": "number" } - ] - } + { "type": "string" }, { "type": "number" } ], "unevaluatedItems": false } -- ["foo", 42] - // All the array items are evaluated. The schema passes validation. + // All the values are evaluated. The schema passes validation. --X ["foo", 42, null] - // The third value is unevaluated, so ``unevaluatedItems`` is true, - // not false. The schema fails validation. + // The schema fails validation because ``"unevaluatedItems": false"`` + // specifies no extra values should exist. -Note these two restraints, though. First, ``items`` doesn't "see -inside" any instances of ``allOf``, ``anyOf``, or ``oneOf`` in the -same subschema. In this next example, ``items`` ignores ``allOf`` and -thus fails to validate. +``unevaluatedItems`` is used mainly when extending a tuple. So with +this in mind, you can make a "half-closed" schema: something useful +when you want to keep the first two arguments, but also add more in +certain situations. ("Closed" to two arguments in some places, "open" +to more arguments when you need it to be.) .. schema_example:: { - "allOf": [{ "prefixItems": [{ "enum": [1, "a"] }] }], - "items": { "const": 2 } + "$id": "https://example.com/my-tuple", + + "type": "array", + "prefixItems": [ + { "type": "boolean" }, + { "type": "string" } + ], + "unevaluatedItems": false, + + "$defs": { + "closed": { + "$anchor": "closed", + "$ref": "#" + } + } } - --X - [1, "a", 2] -Second, ``unevaluatedItems`` can't "see inside" cousins (vertically -adjacent properties inside a separate pair of {curly braces} with the -same "parent"— ``anyOf``, ``if``, ``not``, or similar). For instance, -in the example below, the ``unevaluatedItems`` doesn't "see inside" -the ``prefixItems`` cousin before it. All instances fail validation -because ``"prefixItems": [ true ]`` matches only length 1 arrays, and -``{ "unevaluatedItems": false }`` matches only empty arrays. +Here the schema is "closed" to two array items. You can then later +use ``$ref`` and add another item like this: .. schema_example:: { - "allOf": [ - { "prefixItems": [true] }, - { "unevaluatedItems": false } - ] + "$id": "https://example.com/my-extended-tuple", + + "$ref": "https://example.com/my-tuple", + "prefixItems": [ + { "type": "boolean" }, + { "type": "string" }, + { "type": "number" } + ], + "unevaluatedItems": false, + + "$defs": { + "extended": { + "$anchor": "extended", + "$ref": "#" + } + } } - --X - [1] -.. note:: - For a tall list of more examples, read our `unevaluatedItems Test Suite `_ on GitHub. We test a lot of use cases - there, including uncommon ones. - -Here are some of our examples in the suite: - * ``unevaluatedItems`` nested inside another ``unevaluatedItems`` - * ``if/then/else`` statements interacting with ``unevaluatedItems`` - * nested ``if/then/else`` statements interacting with ``unevaluatedItems`` - * ``unevaluatedItems`` ignoring non-arrays - * ``unevaluatedItems`` interacting with the ``not`` keyword - * and more +Thus, you would reference ``my-tuple#closed`` when you need only +two array items and reference ``my-tuple#extended`` when you need +three items. .. index:: single: array; contains From 9eb6e3dab4a16a8e58dba1c1b9fb8ca15bb05068 Mon Sep 17 00:00:00 2001 From: Michael Sharber <112581105+micshar92@users.noreply.github.com> Date: Sat, 24 Jun 2023 15:25:17 -0500 Subject: [PATCH 8/9] eighth and maybe final draft of ``unevaluatedItems`` tutorial --- source/reference/array.rst | 80 +++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/source/reference/array.rst b/source/reference/array.rst index ed4ba21e..e42f968a 100644 --- a/source/reference/array.rst +++ b/source/reference/array.rst @@ -236,82 +236,83 @@ Unevaluated Items |draft2019-09| -The ``unevaluatedItems`` keyword applies to any values not evaluated -by an ``items``, ``prefixItems``, or ``contains`` keyword. Just as +The ``unevaluatedItems`` keyword is useful mainly when you want to add +or disallow extra items to an array. + +``unevaluatedItems`` applies to any values not evaluated by an +``items``, ``prefixItems``, or ``contains`` keyword. Just as ``unevaluatedProperties`` affects only **properties** in an object, ``unevaluatedItems`` affects only **items** in an array. .. note:: Watch out! The word "unevaluated" *does not mean* "not evaluated by ``items``, ``prefixItems``, or ``contains``." "Unevaluated" means - "not successfully evaluated", or "doesn't evaluate to true". + "not successfully evaluated", or "does not evaluate to true". -``items`` doesn't "see inside" any instances of ``allOf``, ``anyOf``, -or ``oneOf`` in the same subschema. In this first example, ``items`` -ignores ``allOf`` and thus fails to validate. +Like with ``items``, if you set ``unevaluatedItems`` to ``false``, you +can disallow extra items in the array. .. schema_example:: { - "allOf": [{ "prefixItems": [{ "type": "boolean" }, { "type": "string" }] }], - "items": { "const": 2 } + "prefixItems": [ + { "type": "string" }, { "type": "number" } + ], + "unevaluatedItems": false } + -- + ["foo", 42] + // All the values are evaluated. The schema passes validation. --X - [true, "a", 2] + ["foo", 42, null] + // The schema fails validation because ``"unevaluatedItems": false"`` + // specifies no extra values should exist. -But if you replace ``items`` with ``unevaluatedItems``, then the same -array validates. +Note that ``items`` doesn't "see inside" any instances of ``allOf``, +``anyOf``, or ``oneOf`` in the same subschema. So in this next example, +``items`` ignores ``allOf`` and thus fails to validate. .. schema_example:: { "allOf": [{ "prefixItems": [{ "type": "boolean" }, { "type": "string" }] }], - "unevaluatedItems": { "const": 2 } + "items": { "const": 2 } } - -- + --X [true, "a", 2] -Like with ``items``, if you set ``unevaluatedItems`` to ``false``, you -can disallow extra items in the array. +But if you replace ``items`` with ``unevaluatedItems``, then the same +array validates. .. schema_example:: { - "prefixItems": [ - { "type": "string" }, { "type": "number" } - ], - "unevaluatedItems": false + "allOf": [{ "prefixItems": [{ "type": "boolean" }, { "type": "string" }] }], + "unevaluatedItems": { "const": 2 } } -- - ["foo", 42] - // All the values are evaluated. The schema passes validation. - --X - ["foo", 42, null] - // The schema fails validation because ``"unevaluatedItems": false"`` - // specifies no extra values should exist. + [true, "a", 2] -``unevaluatedItems`` is used mainly when extending a tuple. So with -this in mind, you can make a "half-closed" schema: something useful -when you want to keep the first two arguments, but also add more in -certain situations. ("Closed" to two arguments in some places, "open" -to more arguments when you need it to be.) +You can also make a "half-closed" schema: something useful when you +want to keep the first two arguments, but also add more in certain +situations. ("Closed" to two arguments in some places, "open" to +more arguments when you need it to be.) .. schema_example:: { "$id": "https://example.com/my-tuple", - "type": "array", "prefixItems": [ { "type": "boolean" }, { "type": "string" } ], - "unevaluatedItems": false, "$defs": { "closed": { "$anchor": "closed", - "$ref": "#" + "$ref": "#", + "unevaluatedItems": false } } } @@ -323,26 +324,25 @@ use ``$ref`` and add another item like this: { "$id": "https://example.com/my-extended-tuple", - "$ref": "https://example.com/my-tuple", "prefixItems": [ { "type": "boolean" }, { "type": "string" }, { "type": "number" } ], - "unevaluatedItems": false, "$defs": { - "extended": { - "$anchor": "extended", - "$ref": "#" + "closed": { + "$anchor": "closed", + "$ref": "#", + "unevaluatedItems": false } } } Thus, you would reference ``my-tuple#closed`` when you need only -two array items and reference ``my-tuple#extended`` when you need -three items. +two items and reference ``my-tuple#extended`` when you need three +items. .. index:: single: array; contains From ba784459e2ad0c62060fc978ff370820dff7c68d Mon Sep 17 00:00:00 2001 From: Michael Sharber <112581105+micshar92@users.noreply.github.com> Date: Tue, 27 Jun 2023 13:55:34 -0500 Subject: [PATCH 9/9] whitespace fix Co-authored-by: Jason Desrosiers --- source/reference/array.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/reference/array.rst b/source/reference/array.rst index e42f968a..d87e5ea8 100644 --- a/source/reference/array.rst +++ b/source/reference/array.rst @@ -331,11 +331,11 @@ use ``$ref`` and add another item like this: { "type": "number" } ], - "$defs": { - "closed": { - "$anchor": "closed", - "$ref": "#", - "unevaluatedItems": false + "$defs": { + "closed": { + "$anchor": "closed", + "$ref": "#", + "unevaluatedItems": false } } }