feat: Add examples #54

Merged
JCHacking merged 14 commits from examples into main 2025-11-23 23:10:27 +00:00
3 changed files with 43 additions and 9 deletions
Showing only changes of commit 84292cf3c0 - Show all commits

View File

@@ -2,21 +2,28 @@ from jambo.exceptions import InvalidSchemaException
from jambo.parser._type_parser import GenericTypeParser from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions from jambo.types.type_parser_options import TypeParserOptions
from typing_extensions import Iterable, TypeVar, Unpack from typing_extensions import (
Callable,
Generic,
Iterable,
Optional,
TypeVar,
Union,
Unpack,
)
import copy import copy
V = TypeVar("V") V = TypeVar("V")
T = TypeVar("T", bound=list)
class ArrayTypeParser(GenericTypeParser): class ArrayTypeParser(GenericTypeParser, Generic[T, V]):
mapped_type = list mapped_type = list
json_schema_type = "type:array" json_schema_type = "type:array"
default_mappings = {"description": "description"}
type_mappings = { type_mappings = {
"maxItems": "max_length", "maxItems": "max_length",
"minItems": "min_length", "minItems": "min_length",
@@ -43,14 +50,25 @@ class ArrayTypeParser(GenericTypeParser):
mapped_properties = self.mappings_properties_builder(properties, **kwargs) mapped_properties = self.mappings_properties_builder(properties, **kwargs)
if "default" in properties or not kwargs.get("required", False): if (
default_value := mapped_properties.pop("default", None)
) is not None or not kwargs.get("required", False):
mapped_properties["default_factory"] = self._build_default_factory( mapped_properties["default_factory"] = self._build_default_factory(
properties.get("default"), wrapper_type default_value, wrapper_type
) )
if (
example_values := mapped_properties.pop("example_values", None)
) is not None:
mapped_properties["examples"] = [
wrapper_type(example) for example in example_values
]
return field_type, mapped_properties return field_type, mapped_properties
def _build_default_factory(self, default_list, wrapper_type): def _build_default_factory(
self, default_list: Optional[Iterable[V]], wrapper_type: type[V]
) -> Callable[[], Union[V, None]]:
if default_list is None: if default_list is None:
return lambda: None return lambda: None

View File

@@ -23,12 +23,12 @@ class ObjectTypeParser(GenericTypeParser):
) )
type_properties = self.mappings_properties_builder(properties, **kwargs) type_properties = self.mappings_properties_builder(properties, **kwargs)
if (default_value := type_properties.get("default")) is not None: if (default_value := type_properties.pop("default", None)) is not None:
type_properties["default_factory"] = lambda: type_parsing.model_validate( type_properties["default_factory"] = lambda: type_parsing.model_validate(
default_value default_value
) )
if (example_values := type_properties.get("examples")) is not None: if (example_values := type_properties.pop("examples", None)) is not None:
type_properties["examples"] = [ type_properties["examples"] = [
type_parsing.model_validate(example) for example in example_values type_parsing.model_validate(example) for example in example_values
] ]

View File

@@ -109,3 +109,19 @@ class TestArrayTypeParser(TestCase):
with self.assertRaises(InvalidSchemaException): with self.assertRaises(InvalidSchemaException):
parser.from_properties("placeholder", properties) parser.from_properties("placeholder", properties)
def test_array_parser_with_examples(self):
parser = ArrayTypeParser()
properties = {
"items": {"type": "integer"},
"examples": [
[1, 2, 3],
[4, 5, 6],
],
}
type_parsing, type_validator = parser.from_properties("placeholder", properties)
self.assertEqual(type_parsing.__origin__, list)
self.assertEqual(type_validator["examples"], [[1, 2, 3], [4, 5, 6]])