keleshev / schema

Schema validation just got Pythonic
MIT License
2.86k stars 214 forks source link

Potential Bug; Unexpeted Behavior (Can't find reason) #288

Open MrChadMWood opened 1 year ago

MrChadMWood commented 1 year ago

I am attempting to validate filters passed via JSON like so:

schema_numericValue = Schema(Or({'int64_value':int}, {'double_value':float}))

schema_stringFilter = Schema({
    'match_type' : Or(
        'EXACT',
        'BEGINS_WITH',
        'ENDS_WITH',
        'CONTAINS',
        'FULL_REGEXP',
        'PARTIAL_REGEXP',
        only_one=True
    ),
    'value' : str,
    Optional('case_sensitive') : bool
})

schema_inListFilter = Schema({
    'values' : [str],
    Optional('case_sensitive') : bool
})

schema_betweenFilter = Schema({
    'from_value' : schema_numericValue,
    'to_value' : schema_numericValue
})

schema_numericFilter = Schema({
    'operation' : Or(
        'EQUAL',
        'GREATER_THAN',
        'GREATER_THAN_OR_EQUAL',
        'LESS_THAN',
        'LESS_THAN_OR_EQUAL',
        only_one=True
    ),
    'value' : schema_numericValue
})

schema_filter = Schema({
    'field_name' : str,
    Or(
        'string_filter', 
        'in_list_filter', 
        'numeric_filter', 
        'between_filter',
        only_one=True
    ) : Or(schema_inListFilter,
           schema_stringFilter,
           schema_numericFilter,
           schema_betweenFilter,
           only_one=True
          )
})

schema_basicFilterExpression = Schema({
    Or(
        'filter', 
        'not_expression', 
        only_one=True
    ) : schema_filter
})

schema_basicFilterExpressionList = Schema({
    'expressions' : [schema_basicFilterExpression]
})

schema_intermediateFilterExpression = Schema({
    Or(
        'and_group',
        'or_group',
        'not_expression',
        'filter',
        only_one=True
    ) : Or(schema_basicFilterExpressionList,
           schema_basicFilterExpression,
           schema_filter,
           only_one=True)
})

schema_intermediateFilterExpressionList = Schema({
    'expressions' : [schema_intermediateFilterExpression]
})

schema_FilterExpression = Schema({
    Or(
        'and_group',
        'or_group',
        'not_expression',
        'filter',
        only_one=True
    ) : Or(schema_intermediateFilterExpressionList,
           schema_intermediateFilterExpression,
           only_one=True)
})

Attempting to validate at a sub-level like so

schema_filter.validate({'field_name': 'p', 'in_list_filter': {'values': ['p', 'p']}})

This produces the following error:

Key 'in_list_filter' error:
Or(Schema({'values': [<class 'str'>], Optional('case_sensitive'): <class 'bool'>}), Schema({'match_type': Or('EXACT', 'BEGINS_WITH', 'ENDS_WITH', 'CONTAINS', 'FULL_REGEXP', 'PARTIAL_REGEXP'), 'value': <class 'str'>, Optional('case_sensitive'): <class 'bool'>}), Schema({'operation': Or('EQUAL', 'GREATER_THAN', 'GREATER_THAN_OR_EQUAL', 'LESS_THAN', 'LESS_THAN_OR_EQUAL'), 'value': Schema(Or({'int64_value': <class 'int'>}, {'double_value': <class 'float'>}))}), Schema({'from_value': Schema(Or({'int64_value': <class 'int'>}, {'double_value': <class 'float'>})), 'to_value': Schema(Or({'int64_value': <class 'int'>}, {'double_value': <class 'float'>}))})) did not validate {'values': ['p', 'p']}

I attempt removing the Or() statement from the value section. only checking for the schema I'm passing at the moment. When I do this, it works.

MrChadMWood commented 1 year ago

Alright, seems this issue is being caused by the only_one=True argument. When this is omitted, problem solved.

Am I doing something wrong?