I am a big fan of python jsonshema. I recently found the if/then/else options which I really like.
However, I have a huge problem with it. Let's say I have:
{
"required": ["PROP1"],
"additionalProperties": True,
"properties": {
"PROP1": {"enum": ["PROP1_CHOICE1", "PROP1_CHOICE2"]}
},
"allOf": [
{
"if": {
"properties": {
"PROP1": {"enum": ["PROP1_CHOICE1"]}
}
},
"then": {
"required": ["PROP2"],
"properties": {
"PROP2": {"type": "string"},
}
},
"else": False
},
{
"if": {
"properties": {
"PROP1": {"enum": ["PROP1_CHOICE2"]}
}
},
"then": {
"required": ["PROP2"],
"properties": {
"PROP2": {"type": "boolean"},
}
},
"else": False
},
]
}
Now assuming I test the following file:
{
"PROP1": "PROP1_CHOICE1",
"PROP2": true
}
I get an error as expected, which is:
jsonschema.exceptions.ValidationError: False schema does not allow {'PROP1': 'PROP1_CHOICE1', 'PROP2': True}
Failed validating None in schema['allOf'][1]:
False
On instance:
{'PROP1': 'PROP1_CHOICE1', 'PROP2': True}
However what I would really like is to obtain the error as if my "PROP_CHOICE2" would not be present in the if/then/else statement, which would be:
jsonschema.exceptions.ValidationError: True is not of type 'string'
Failed validating 'type' in schema['allOf'][0]['then']['properties']['PROP2']:
{'type': 'string'}
On instance['PROP2']:
True
I did find a work around for this which is to execute the if/then/else statements sequentially like this:
{
"required": ["PROP1"],
"additionalProperties": True,
"properties": {
"PROP1": {"enum": ["PROP1_CHOICE1", "PROP1_CHOICE2"]}
},
"if": {
"properties": {
"PROP1": {"enum": ["PROP1_CHOICE1"]}
}
},
"then": {
"required": ["PROP2"],
"properties": {
"PROP2": {"type": "string"},
}
},
"else": {
"if": {
"properties": {
"PROP1": {"enum": ["PROP1_CHOICE2"]}
}
},
"then": {
"required": ["PROP2"],
"properties": {
"PROP2": {"type": "boolean"},
}
},
"else": False
}
}
This does resolve my issue but now the issue becomes the indentation level which can quickly increase if you have multiple if/then/else statements.
Is there a way to get a code similar to the first code sample of this question with the output of the second code sample (specific error message without increasing indentation level similar to a switch/case statement) ?
Please note that this issue is particularly problematic for big shema (if I keep first code sample than the error can't pinpoint the specific schema issue and if I put in place my solution, then my indentation level becomes crappy).
With the input from @Jason Desrosiers I now get the expected output as desired and found a way to keep the else statements (so I can deal with all forgotten enum options). Here is the new definition:
{
"required": ["PROP1"],
"additionalProperties": True,
"properties": {
"PROP1": {"enum": ["PROP1_CHOICE1", "PROP1_CHOICE2", "PROP_CHOICE_3"]}
},
"allOf": [
{
"if": {
"properties": {
"PROP1": {"const": "PROP1_CHOICE1"}
}
},
"then": {
"required": ["PROP2"],
"properties": {
"PROP2": {"type": "string"},
}
}
},
{
"if": {
"properties": {
"PROP1": {"const": "PROP1_CHOICE2"}
}
},
"then": {
"required": ["PROP2"],
"properties": {
"PROP2": {"type": "boolean"},
}
},
},
{
"else": False
}
]
}
Thx @Jason Desrosiers
With this I now get (as expected, Yeah!):
jsonschema.exceptions.ValidationError: True is not of type 'string'
Failed validating 'type' in schema['allOf'][0]['then']['properties']['PROP2']:
{'type': 'string'}
On instance['PROP2']:
True
And let's say I try forgotten "PROP_CHOICE_3" if statement I now get:
jsonschema.exceptions.ValidationError: 'PROP1_CHOICE3' is not one of ['PROP1_CHOICE1', 'PROP1_CHOICE2', 'PROP_CHOICE_3']
Failed validating 'enum' in schema['properties']['PROP1']:
{'enum': ['PROP1_CHOICE1', 'PROP1_CHOICE2', 'PROP_CHOICE_3']}
On instance['PROP1']:
'PROP1_CHOICE3'