Skip to content

Unable to set defaults when required appears first in schema #1082

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

Closed
ShadowLNC opened this issue Apr 7, 2023 · 2 comments
Closed

Unable to set defaults when required appears first in schema #1082

ShadowLNC opened this issue Apr 7, 2023 · 2 comments

Comments

@ShadowLNC
Copy link

I followed the steps in the docs to populate default values. In my schema, I have a required declaration, with the implication being that defaults should be populated before it is evaluated.

When I set schema = {'required': ['foo'], 'properties': {'foo': {'default': 'bar'}}}, validation fails as required appears to be evaluated before the default is set.

If I change the order of declaration to be schema = {'properties': {'foo': {'default': 'bar'}}, 'required': ['foo']}, validation succeeds.

My schema is a JSON value that is being loaded in by json.loads, rather than a schema I define in Python.

Per the JSON docs, "An object is an unordered set of name/value pairs." I take this to mean that the behaviour should be the same regardless of the order of the key-value pairs.

Is there a way that we can avoid relying on required being defined after properties?

@ShadowLNC
Copy link
Author

I did search but apparently not thoroughly enough - this appears to be a duplicate of #742 - apologies!

I wonder if this should be documented as part of the linked FAQ? Feel free to close this issue, but I foresee issues where the consumer of the schema has no control over the schema itself, and I'm not sure how best to address that.

Maybe required could be "demoted" to the bottom of the processing list? But I guess that might still run into issues with other keywords

@ShadowLNC
Copy link
Author

My workaround is as follows for now:

from contextlib import suppress
from typing import Any

def reorder_required(data: dict[str, Any]) -> None:
    """Modify dictionaries by reference to ensure `required` is after `properties`."""
    with suppress(KeyError):
        val = data["required"]
        del data["required"]
        data["required"] = val
    for v in data.values():
        if isinstance(v, dict):
            reorder_required(v)

reorder_required(schema)

Not the most elegant, but it seems to get the job done. I'll close this for now 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant