Skip to content

Commit

Permalink
Make 'required' keys that are not in 'properties' be validated agains…
Browse files Browse the repository at this point in the history
…t additionalProperties
  • Loading branch information
hudson-ai committed Sep 16, 2024
1 parent b424a32 commit 31353f3
Showing 1 changed file with 17 additions and 8 deletions.
25 changes: 17 additions & 8 deletions guidance/library/_json.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from json import dumps as json_dumps
from enum import Enum
from itertools import chain
from typing import (
Any,
Callable,
Expand Down Expand Up @@ -359,16 +360,24 @@ def _gen_json_object(
required: Sequence[str],
definitions: Mapping[str, Callable[[], GrammarFunction]],
):
if any(k not in properties for k in required):
raise ValueError(f"Required properties not in properties: {set(required) - set(properties)}")

grammars = tuple(f'"{name}":' + _gen_json(json_schema=schema, definitions=definitions) for name, schema in properties.items())
required_items = tuple(name in required for name in properties)
# "required" keys will be validated against "properties" if they're present, otherwise against "additionalProperties".
# If "additionalProperties" is False, then required keys must be in "properties".
if any(k not in properties for k in required) and additional_properties is False:
raise ValueError(
f"Required properties not in properties but additionalProperties is False."
f" Missing required properties: {set(required) - set(properties)}"
)
items = list(chain(
# First iterate over the properties in order
properties.items(),
# If there are any keys in required that weren't specified by properties, add them in order at the end,
# where we will validate against the additional_properties schema
((key, additional_properties) for key in required if key not in properties),
))
grammars = tuple(f'"{name}":' + _gen_json(json_schema=schema, definitions=definitions) for name, schema in items)
required_items = tuple(name in required for name, _ in items)

if additional_properties is not False:
if additional_properties is True:
# True means that anything goes
additional_properties = {}
additional_item_grammar = _gen_json_string() + ':' + _gen_json(json_schema=additional_properties, definitions=definitions)
additional_items_grammar = sequence(additional_item_grammar + ',') + additional_item_grammar
grammars += (additional_items_grammar,)
Expand Down

0 comments on commit 31353f3

Please sign in to comment.