diff options
author | Harald Nezbeda <hn@nezhar.com> | 2021-06-21 11:15:28 +0200 |
---|---|---|
committer | Harald Nezbeda <hn@nezhar.com> | 2021-07-19 18:14:31 +0200 |
commit | 45ee736b9eaf5d5e0eafb1fbf7658582af3dd1ce (patch) | |
tree | 3a51f50bb953a5818ef304a66751b11dd4fab124 /jsonschema/_utils.py | |
parent | bb8b7eee22e986b5f8c682e30c38a05e474e53d8 (diff) | |
download | jsonschema-45ee736b9eaf5d5e0eafb1fbf7658582af3dd1ce.tar.gz |
Julian/jsonschema#782: Implements unevaluatedProperties validations
Diffstat (limited to 'jsonschema/_utils.py')
-rw-r--r-- | jsonschema/_utils.py | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/jsonschema/_utils.py b/jsonschema/_utils.py index 100b653..be52f66 100644 --- a/jsonschema/_utils.py +++ b/jsonschema/_utils.py @@ -238,7 +238,7 @@ def find_evaluated_item_indexes_by_schema(validator, instance, schema): """ Get all indexes of items that get evaluated under the current schema - Covers are keywords related t unevaluatedItems: items, prefixItems, if, then, else, 'contains', 'unevaluatedItems', + Covers all keywords related to unevaluatedItems: items, prefixItems, if, then, else, 'contains', 'unevaluatedItems', 'allOf', 'oneOf', 'anyOf' """ if not validator.is_type(schema, "object"): @@ -274,3 +274,61 @@ def find_evaluated_item_indexes_by_schema(validator, instance, schema): evaluated_item_indexes += find_evaluated_item_indexes_by_schema(validator, instance, subschema) return evaluated_item_indexes + + +def find_evaluated_property_keys_by_schema(validator, instance, schema): + """ + Get all keys of items that get evaluated under the current schema + + Covers all keywords related to unevaluatedProperties: properties, 'additionalProperties', 'unevaluatedProperties', + patternProperties, dependentSchemas, 'allOf', 'oneOf', 'anyOf', if, then, else + """ + if not validator.is_type(schema, "object"): + return [] + evaluated_property_keys = [] + + for keyword in ['properties', 'additionalProperties', 'unevaluatedProperties']: + if keyword in schema: + if validator.is_type(schema[keyword], "boolean"): + for property, value in instance.items(): + if validator.is_valid({property: value}, schema[keyword]): + evaluated_property_keys.append(property) + + if validator.is_type(schema[keyword], "object"): + for property, subschema in schema[keyword].items(): + if property in instance and validator.is_valid(instance[property], subschema): + evaluated_property_keys.append(property) + + if 'patternProperties' in schema: + for property, value in instance.items(): + for pattern, subschema in schema['patternProperties'].items(): + if re.search(pattern, property): + if validator.is_valid({property: value}, schema['patternProperties']): + evaluated_property_keys.append(property) + + if 'dependentSchemas' in schema: + for property, subschema in schema['dependentSchemas'].items(): + if property not in instance: + continue + + errs = list(validator.descend(instance, subschema)) + if not errs: + evaluated_property_keys += find_evaluated_property_keys_by_schema(validator, instance, subschema) + + for keyword in ['allOf', 'oneOf', 'anyOf']: + if keyword in schema: + for subschema in schema[keyword]: + errs = list(validator.descend(instance, subschema)) + if not errs: + evaluated_property_keys += find_evaluated_property_keys_by_schema(validator, instance, subschema) + + if 'if' in schema: + if validator.is_valid(instance, schema['if']): + evaluated_property_keys += find_evaluated_property_keys_by_schema(validator, instance, schema['if']) + if 'then' in schema: + evaluated_property_keys += find_evaluated_property_keys_by_schema(validator, instance, schema['then']) + else: + if 'else' in schema: + evaluated_property_keys += find_evaluated_property_keys_by_schema(validator, instance, schema['else']) + + return evaluated_property_keys |