diff --git a/jambo/parser/anyof_type_parser.py b/jambo/parser/anyof_type_parser.py index 9b09754..c0295ff 100644 --- a/jambo/parser/anyof_type_parser.py +++ b/jambo/parser/anyof_type_parser.py @@ -31,7 +31,7 @@ class AnyOfTypeParser(GenericTypeParser): sub_types = [ GenericTypeParser.type_from_properties( - f"{name}_sub{i}", subProperty, **kwargs + f"{name}.sub{i}", subProperty, **kwargs ) for i, subProperty in enumerate(sub_properties) ] diff --git a/jambo/parser/object_type_parser.py b/jambo/parser/object_type_parser.py index fc10cb5..475c785 100644 --- a/jambo/parser/object_type_parser.py +++ b/jambo/parser/object_type_parser.py @@ -67,7 +67,7 @@ class ObjectTypeParser(GenericTypeParser): return model model_config = ConfigDict(validate_assignment=True) - fields = cls._parse_properties(properties, required_keys, **kwargs) + fields = cls._parse_properties(name, properties, required_keys, **kwargs) model = create_model(name, __config__=model_config, **fields) # type: ignore @@ -84,6 +84,7 @@ class ObjectTypeParser(GenericTypeParser): @classmethod def _parse_properties( cls, + name: str, properties: dict[str, JSONSchema], required_keys: list[str], **kwargs: Unpack[TypeParserOptions], @@ -91,15 +92,15 @@ class ObjectTypeParser(GenericTypeParser): required_keys = required_keys or [] fields = {} - for name, prop in properties.items(): + for field_name, field_prop in properties.items(): sub_property: TypeParserOptions = kwargs.copy() - sub_property["required"] = name in required_keys + sub_property["required"] = field_name in required_keys parsed_type, parsed_properties = GenericTypeParser.type_from_properties( - name, - prop, + f"{name}.{field_name}", + field_prop, **sub_property, # type: ignore ) - fields[name] = (parsed_type, Field(**parsed_properties)) + fields[field_name] = (parsed_type, Field(**parsed_properties)) return fields diff --git a/tests/test_schema_converter.py b/tests/test_schema_converter.py index 6cd66ef..245ca8e 100644 --- a/tests/test_schema_converter.py +++ b/tests/test_schema_converter.py @@ -942,3 +942,59 @@ class TestSchemaConverter(TestCase): cached_model = self.converter.get_cached_ref("NonExistentModel") self.assertIsNone(cached_model) + + def test_get_type_from_cache_nested_type(self): + schema = { + "title": "Person", + "type": "object", + "properties": { + "name": {"type": "string"}, + "age": {"type": "integer"}, + "address": { + "type": "object", + "properties": { + "street": {"type": "string"}, + "city": {"type": "string"}, + }, + "required": ["street", "city"], + }, + }, + "required": ["name", "age", "address"], + } + + model = self.converter.build_with_instance(schema) + + cached_model = self.converter.get_cached_ref("Person.address") + + self.assertIsNotNone(cached_model) + self.assertIs(model.model_fields["address"].annotation, cached_model) + + def test_get_type_from_cache_with_def(self): + schema = { + "title": "person", + "type": "object", + "properties": { + "name": {"type": "string"}, + "age": {"type": "integer"}, + "address": {"$ref": "#/$defs/address"}, + }, + "$defs": { + "address": { + "type": "object", + "properties": { + "street": {"type": "string"}, + "city": {"type": "string"}, + }, + "required": ["street", "city"], + } + }, + } + + person_model = self.converter.build_with_instance(schema) + cached_person_model = self.converter.get_cached_ref("person") + + self.assertIs(person_model, cached_person_model) + + cached_address_model = self.converter.get_cached_ref("address") + + self.assertIsNotNone(cached_address_model)