From f80a1bbda35246d198dadef9d17d4db1872ac00b Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Sun, 23 Nov 2025 21:40:54 -0300 Subject: [PATCH 1/2] feat: fixes error of multiple forwardref with same name --- jambo/parser/oneof_type_parser.py | 8 +++--- tests/test_schema_converter.py | 47 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/jambo/parser/oneof_type_parser.py b/jambo/parser/oneof_type_parser.py index 11092ea..3c55763 100644 --- a/jambo/parser/oneof_type_parser.py +++ b/jambo/parser/oneof_type_parser.py @@ -29,11 +29,11 @@ class OneOfTypeParser(GenericTypeParser): mapped_properties = self.mappings_properties_builder(properties, **kwargs) - sub_properties = properties["oneOf"] - sub_types = [ - GenericTypeParser.type_from_properties(name, subProperty, **kwargs) - for subProperty in sub_properties + GenericTypeParser.type_from_properties( + f"{name}_sub{i}", subProperty, **kwargs + ) + for i, subProperty in enumerate(properties["oneOf"]) ] if not kwargs.get("required", False): diff --git a/tests/test_schema_converter.py b/tests/test_schema_converter.py index 6f2b15a..f8a0f48 100644 --- a/tests/test_schema_converter.py +++ b/tests/test_schema_converter.py @@ -1,5 +1,6 @@ from jambo import SchemaConverter from jambo.exceptions import InvalidSchemaException, UnsupportedSchemaException +from jambo.types import JSONSchema from pydantic import AnyUrl, BaseModel, ValidationError @@ -791,3 +792,49 @@ class TestSchemaConverter(TestCase): with self.assertRaises(ValidationError): Model(a_thing="not none") + + def test_scoped_ref_schema(self): + schema: JSONSchema = { + "title": "Example Schema", + "type": "object", + "properties": { + "operating_system": { + "oneOf": [ + {"$ref": "#/$defs/operating_system"}, + { + "type": "object", + "properties": { + "creation": {"$ref": "#/$defs/operating_system"}, + "reinstallation": {"$ref": "#/$defs/operating_system"}, + }, + "required": ["creation", "reinstallation"], + }, + ] + }, + }, + "$defs": { + "operating_system": { + "type": "object", + "properties": { + "name": {"type": "string"}, + "version": {"type": "string"}, + }, + "required": ["name", "version"], + } + }, + } + + schema_type = SchemaConverter.build(schema) + + _ = schema_type.model_validate( + {"operating_system": {"name": "Ubuntu", "version": "20.04"}} + ) + + _ = schema_type.model_validate( + { + "operating_system": { + "creation": {"name": "Ubuntu", "version": "20.04"}, + "reinstallation": {"name": "Ubuntu", "version": "22.04"}, + } + } + ) -- 2.49.1 From f15913c58edf211de6c234a9cecffe027e93b3b9 Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Sun, 23 Nov 2025 22:09:55 -0300 Subject: [PATCH 2/2] feat: tests that the generated fields in the oneOf parser have unique names and applies the same logic to the anyOf parser --- jambo/parser/anyof_type_parser.py | 6 ++++-- tests/test_schema_converter.py | 20 +++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/jambo/parser/anyof_type_parser.py b/jambo/parser/anyof_type_parser.py index 4b961ac..9b09754 100644 --- a/jambo/parser/anyof_type_parser.py +++ b/jambo/parser/anyof_type_parser.py @@ -30,8 +30,10 @@ class AnyOfTypeParser(GenericTypeParser): sub_properties = properties["anyOf"] sub_types = [ - GenericTypeParser.type_from_properties(name, subProperty, **kwargs) - for subProperty in sub_properties + GenericTypeParser.type_from_properties( + f"{name}_sub{i}", subProperty, **kwargs + ) + for i, subProperty in enumerate(sub_properties) ] if not kwargs.get("required", False): diff --git a/tests/test_schema_converter.py b/tests/test_schema_converter.py index f8a0f48..77c88c9 100644 --- a/tests/test_schema_converter.py +++ b/tests/test_schema_converter.py @@ -3,6 +3,7 @@ from jambo.exceptions import InvalidSchemaException, UnsupportedSchemaException from jambo.types import JSONSchema from pydantic import AnyUrl, BaseModel, ValidationError +from typing_extensions import get_args from ipaddress import IPv4Address, IPv6Address from unittest import TestCase @@ -826,15 +827,12 @@ class TestSchemaConverter(TestCase): schema_type = SchemaConverter.build(schema) - _ = schema_type.model_validate( - {"operating_system": {"name": "Ubuntu", "version": "20.04"}} - ) + # check for me that the types generated by the oneOf in the typing.Annotated have different names + operating_system_field = schema_type.model_fields["operating_system"] - _ = schema_type.model_validate( - { - "operating_system": { - "creation": {"name": "Ubuntu", "version": "20.04"}, - "reinstallation": {"name": "Ubuntu", "version": "22.04"}, - } - } - ) + arg1, arg2 = get_args(operating_system_field.annotation) + + first_type = get_args(arg1)[0] + second_type = get_args(arg2)[0] + + self.assertNotEqual(first_type.__name__, second_type.__name__) -- 2.49.1