-
-
Notifications
You must be signed in to change notification settings - Fork 308
provide defaults for all keywords and subschemas that lacked them #1006
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
provide defaults for all keywords and subschemas that lacked them #1006
Conversation
What's a concrete example of functionality this provides? My interpretation of "default" is a suitable initial value for the instance when it's created; so at the very least, I think |
This is to restore consistency to the metaschemas. In most other places, a |
Is this good to include in draft2020-xx? |
rebased |
35325a5
to
8d766a4
Compare
8d766a4
to
5d21304
Compare
Hm.. I didn't see this when I did #1057. May have duplication. |
Given that we don't provide defaults in the same schema object which uses a ref or dynamic ref, we should remove that found in the applicator vocab schema on line 17, right? json-schema-spec/meta/applicator.json Lines 15 to 18 in 77686de
And for I think I'll merge this as best I can, then remove the defaults where |
Can this be rebased one more time please? |
For vocabulary metaschemas, the default is just 'true'; for the 'dependentRequired' and 'dependentSchemas' keywords, the default is the empty object.
5d21304
to
9eef7bf
Compare
rebased! |
meta/core.json
Outdated
@@ -48,5 +48,6 @@ | |||
"type": "string", | |||
"format": "uri-reference" | |||
} | |||
} | |||
}, | |||
"default": true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't agree with having defaults in the roots of the meta-schemas. What's the motivation for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get that the motivation is to avoid putting "default": true
everywhere we reference a schema, but the default isn't always "true" for all references.
Traditionally, in our meta-schemas, default
has meant something like: if this doesn't exist, the validation result would be the same as if it did exist and had this default value. For example, the default
of properties
is {}
. Therefore, {}
has the same result as { "properties": {} }
.
So, now consider the not
keyword. It references the top-level meta-schema. If the top-level meta-schema has "default": true
that says the default
of not
is true
. Therefore, {}
has the same result as { "not": true }
, which is not correct. That means each time something references the top-level meta-schema it needs to define a default
that makes sense in its context.
... or just get rid of default
in meta-schemas altogether because it doesn't provide any real value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jdesrosiers I think we're arguing the same side of the coin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we are. Bottom line is that default
doesn't belong at the root of meta-schemas.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, now consider the not keyword. It references the top-level meta-schema. If the top-level meta-schema has "default": true that says the default of not is true. Therefore, {} has the same result as { "not": true }, which is not correct. That means each time something references the top-level meta-schema it needs to define a default that makes sense in its context.
Or, we can add a default for not -- which should be false. that is, ..., "not": { "$dynamicRef": "#meta", "default": false }, ...
So, how about we remove all uses of default where it's just the obvious thing ({}
for objects, []
for arrays, or true
or {}
for schemas), and keep them only when they're non-standard -- which is, I believe, just "not", "deprecated", "readOnly", "writeOnly", "uniqueItems", and "minContains".)
If that's amenable to all I can amend this PR.
In the end, this is the diff I get against master. is this what we want?
|
e.g. when evaluating the "not" keyword, the subschema inside it should *not* be true, as that would produce a false result from this keyword
Given that we have been using the default keyword wrong anyway (missing keywords cannot produce annotations), maybe something like this is more correct: https://gist.github.com/karenetheridge/1239b063611b937c38713f6ac6a6eaa6 |
That has never occurred to me. We would only know the
If an entire schema is missing, I would expect this It seems |
Well, the user can do whatever he likes with the annotations he gets back -- it doesn't have to be all or nothing. In some of my code (that is, the caller of the json schema evaluator - not the evaluator itself!), I retrieve that default annotation and add its values into the data instance for every property that is missing. |
Here's another approach we might take with where we use If a keyword isn't present it has no effect. There's no reason to declare a default value that also has no effect. The only reason to have a default value is for keywords that depend on other keywords for their results. In order to process
|
I think we can leave out properties and patternProperties too -- as the spec says what to do if those keywords are missing (no keyword -> no annotation -> nothing to consume when considering the result of additionalProperties, unevaluatedProperties). We can leave out if/then/else and not as well -- no keyword -> nothing to do -> no false value injected into the result. The only outliers really are "minContains", which defaults to 1 when absent, and the meta-data keywords which default to false. We should be able to drop all the rest. edit: and '$schema', which defaults to the main metaschema $id. |
I think I agree Others to consider are
I think it would be a nice-to-have to include these defaults, but not necessary. |
I pushed another commit for consideration, which would be squashed with the other two if acceptable. |
…only include those that insert different behaviour than would exist if they were absent
dc338ab
to
a33ef8f
Compare
…duce no annotations
meta/core.json
Outdated
} | ||
}, | ||
"default": { | ||
"$schema": "https://json-schema.org/draft/2020-12/schema" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't this mean that every schema, including sub-schemas, have a $schema
keyword. $schema
has no effect in sub-schemas, so this doesn't make sense to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good point. So we'll have to leave it out.. as we have no way currently of specifying in the metaschema "this should apply for the top level schema but not for anything dynamically referenced lower down".
I agree that Not a hard objection, just my preference. I won't argue if others like it. |
This is close to my conclusion too, see #867 |
meta/validation.json
Outdated
"default": { | ||
"minContains": 1 | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of this format, and I don't think we should encourage it. I think the default value should stay with the property declaration.
meta/validation.json
Outdated
}, | ||
"maxContains": { "$ref": "#/$defs/nonNegativeInteger" }, | ||
"minContains": { | ||
"$ref": "#/$defs/nonNegativeInteger", | ||
"default": 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should stay
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we're okay with using "default" totally contradictory to the spec? If this is here purely for humans, it should be in a $comment
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this use is contradictory to the spec, because the spec defines default
so broadly that there is no wrong way to use it. Since there is no right or wrong way to use it and it doesn't do anything anyway, I'd rather use it in the spirit of how it was intended to be used.
If this is here purely for humans, it should be in a
$comment
.
I had the same thought at first, but I've come to the conclusion that just because default
is not useful as an annotation, doesn't mean it's not useful. Consider that a documentation generator doesn't use instances and therefore doesn't work on annotations as they are defined by the spec. The documentation generator can still make good use of default
because the limitations of using it as an annotation don't apply in that context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in agreement with this. We should consider other applications beyond just being used with an instance, the most obvious, to me, being writing schemas by hand or using UI tools (in terms of adding these for the meta schema).
I agree with @jdesrosiers's idea of only including defaults for keywords that have other keywords being dependent upon them. Going forward, maybe we need to declare the default values of keywords in the context where they're depended upon. For example, the section for
Note that this doesn't give the |
In agreement with changes requested by @gregsdennis and @jdesrosiers, including those in
|
I don't see how that can be done with current syntax, because anything we put here would be defined at the |
…s that are useful to note for humans.
I have pushed one more commit for consideration. |
Yeah, it can't. Was just thinking out loud. |
So the net result of this PR is Do we want to handle defaults for |
The net result is that defaults have been removed for all subschemas that recursively-reference prefixItems already has a default, via the schemaArray definition, and items is another |
I can squash with a better commit message if we're good with this (or let Relequestual do it). |
- Remove `default` from all subschemas that recursively-reference #meta - Add `default to `dependencies` Remove, e.g. when evaluating the "not" keyword, the subschema inside it should *not* be true, as that would produce a false result from this keyword.
For vocabulary metaschemas, the default is just 'true'; for
the 'dependentRequired' and 'dependentSchemas' keywords, the default is the
empty object.