From 84292cf3c0ee211d0cc6488b3391eb7472c6daa1 Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Sun, 23 Nov 2025 14:59:16 -0300 Subject: [PATCH] feat: fixes and validates so that arrays have parsed examples --- jambo/parser/array_type_parser.py | 32 ++++++++++++++++++++------ jambo/parser/object_type_parser.py | 4 ++-- tests/parser/test_array_type_parser.py | 16 +++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/jambo/parser/array_type_parser.py b/jambo/parser/array_type_parser.py index 790a65a..787e2cc 100644 --- a/jambo/parser/array_type_parser.py +++ b/jambo/parser/array_type_parser.py @@ -2,21 +2,28 @@ from jambo.exceptions import InvalidSchemaException from jambo.parser._type_parser import GenericTypeParser 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 V = TypeVar("V") +T = TypeVar("T", bound=list) -class ArrayTypeParser(GenericTypeParser): +class ArrayTypeParser(GenericTypeParser, Generic[T, V]): mapped_type = list json_schema_type = "type:array" - default_mappings = {"description": "description"} - type_mappings = { "maxItems": "max_length", "minItems": "min_length", @@ -43,14 +50,25 @@ class ArrayTypeParser(GenericTypeParser): 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( - 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 - 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: return lambda: None diff --git a/jambo/parser/object_type_parser.py b/jambo/parser/object_type_parser.py index 516ffc5..b625a6e 100644 --- a/jambo/parser/object_type_parser.py +++ b/jambo/parser/object_type_parser.py @@ -23,12 +23,12 @@ class ObjectTypeParser(GenericTypeParser): ) 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( 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_parsing.model_validate(example) for example in example_values ] diff --git a/tests/parser/test_array_type_parser.py b/tests/parser/test_array_type_parser.py index dc9212f..d394095 100644 --- a/tests/parser/test_array_type_parser.py +++ b/tests/parser/test_array_type_parser.py @@ -109,3 +109,19 @@ class TestArrayTypeParser(TestCase): with self.assertRaises(InvalidSchemaException): 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]])