@@ -477,6 +477,27 @@ def has_ref_with_schema_keywords(self) -> bool:
477477 schema_affecting_fields |= {"extras" }
478478 return bool (schema_affecting_fields )
479479
480+ @cached_property
481+ def is_ref_with_nullable_only (self ) -> bool :
482+ """Check if schema has $ref with only nullable: true (no other schema-affecting keywords).
483+
484+ This is used to avoid creating duplicate models when a $ref is combined
485+ with nullable: true. In such cases, the reference should be used directly
486+ with Optional type annotation instead of merging schemas.
487+ """
488+ if not self .ref or self .nullable is not True :
489+ return False
490+ other_fields = get_fields_set (self ) - {"ref" , "nullable" } - self .__metadata_only_fields__ - {"extras" }
491+ if other_fields :
492+ return False
493+ if self .extras :
494+ schema_affecting_extras = {
495+ k for k in self .extras if k not in self .__metadata_only_fields__ and not k .startswith ("x-" )
496+ }
497+ if schema_affecting_extras :
498+ return False
499+ return True
500+
480501
481502@lru_cache
482503def get_ref_type (ref : str ) -> JSONReference :
@@ -2700,6 +2721,12 @@ def parse_item( # noqa: PLR0911, PLR0912, PLR0914
27002721 item ,
27012722 root_type_path ,
27022723 )
2724+ # Handle $ref + nullable-only case without merging to avoid duplicate models
2725+ if item .is_ref_with_nullable_only and item .ref :
2726+ ref_data_type = self .get_ref_data_type (item .ref )
2727+ if self .strict_nullable :
2728+ return self .data_type (data_types = [ref_data_type ], is_optional = True )
2729+ return ref_data_type
27032730 if item .has_ref_with_schema_keywords :
27042731 item = self ._merge_ref_with_schema (item )
27052732 if item .ref :
@@ -3523,7 +3550,8 @@ def parse_obj( # noqa: PLR0912
35233550 path : list [str ],
35243551 ) -> None :
35253552 """Parse a JsonSchemaObject by dispatching to appropriate parse methods."""
3526- if obj .has_ref_with_schema_keywords :
3553+ # Skip merge for $ref + nullable-only (handled by ref resolution in parse_item)
3554+ if obj .has_ref_with_schema_keywords and not obj .is_ref_with_nullable_only :
35273555 obj = self ._merge_ref_with_schema (obj )
35283556
35293557 if obj .is_array :
0 commit comments