@@ -1564,7 +1564,7 @@ def _create_discriminator_data_type(
15641564 if enum_source :
15651565 if self .use_enum_values_in_discriminator :
15661566 enum_class_name = enum_source .reference .short_name
1567- enum_member_literals : list [tuple [str , DiscriminatorValue ]] = []
1567+ enum_member_literals : list [tuple [str , str ]] = []
15681568 for value in discriminator_values :
15691569 member = enum_source .find_member (value )
15701570 if member and member .field .name :
@@ -1575,24 +1575,28 @@ def _create_discriminator_data_type(
15751575 if enum_source .module_path != discriminator_model .module_path : # pragma: no cover
15761576 imports .append (Import .from_full_path (enum_source .name ))
15771577 else :
1578- # According to OpenAPI specification, mapping discriminators are always string values.
1579- # However, if the mapped object is an enum, we want to use the real enum value instead of
1580- # the string value.
1581- # See: https://swagger.io/specification/#options-for-mapping-values-to-schemas
1582- # Fix: https://github.com/koxudaxi/datamodel-code-generator/issues/3073
1583- for i , value in enumerate (discriminator_values ):
1584- if member := enum_source .find_member (value ):
1585- match member .field .default :
1586- case str ():
1587- discriminator_values [i ] = member .field .default .strip ("'\" " )
1588- case _ if isinstance (member .field .default , DiscriminatorValue ):
1589- discriminator_values [i ] = member .field .default
1590-
1591- data_type = self .data_type (literals = discriminator_values )
1578+ data_type = self .data_type (
1579+ literals = [
1580+ Parser ._get_enum_discriminator_literal (enum_source , value ) for value in discriminator_values
1581+ ]
1582+ )
15921583 else :
15931584 data_type = self .data_type (literals = discriminator_values )
15941585 return data_type
15951586
1587+ @staticmethod
1588+ def _get_enum_discriminator_literal (enum_source : Enum , value : DiscriminatorValue ) -> DiscriminatorValue :
1589+ member = enum_source .find_member (value )
1590+ if not member :
1591+ return value
1592+
1593+ default = member .field .default
1594+ if isinstance (default , str ):
1595+ return default .strip ("'\" " )
1596+ if isinstance (default , int | bool ):
1597+ return default
1598+ return value
1599+
15961600 def __apply_discriminator_type ( # noqa: PLR0912, PLR0914, PLR0915
15971601 self ,
15981602 models : list [DataModel ],
@@ -1706,28 +1710,29 @@ def get_discriminator_field_value(
17061710 msg = f"Discriminator type is not found. { data_type .reference .path } "
17071711 raise RuntimeError (msg )
17081712
1709- enum_from_base : Enum | None = None
1710- for base_class in discriminator_model .base_classes :
1711- if not base_class .reference or not base_class .reference .source : # pragma: no cover
1712- continue
1713- base_model = base_class .reference .source
1714- if not isinstance ( # pragma: no cover
1715- base_model ,
1716- (
1717- pydantic_model_v2 .BaseModel ,
1718- dataclass_model .DataClass ,
1719- msgspec_model .Struct ,
1720- ),
1721- ):
1722- continue
1723- for base_field in base_model .fields : # pragma: no branch
1724- if field_name not in {base_field .original_name , base_field .name }: # pragma: no cover
1713+ def get_enum_from_base (
1714+ discriminator_model : DataModel = discriminator_model ,
1715+ field_name : str = field_name ,
1716+ ) -> Enum | None :
1717+ for base_class in discriminator_model .base_classes :
1718+ if not base_class .reference or not base_class .reference .source : # pragma: no cover
17251719 continue
1726- enum_from_base = base_field .data_type .find_source (Enum )
1727- if enum_from_base : # pragma: no branch
1728- break
1729- if enum_from_base : # pragma: no branch
1730- break
1720+ base_model = base_class .reference .source
1721+ if not isinstance ( # pragma: no cover
1722+ base_model ,
1723+ (
1724+ pydantic_model_v2 .BaseModel ,
1725+ dataclass_model .DataClass ,
1726+ msgspec_model .Struct ,
1727+ ),
1728+ ):
1729+ continue
1730+ for base_field in base_model .fields : # pragma: no branch
1731+ if field_name not in {base_field .original_name , base_field .name }: # pragma: no cover
1732+ continue
1733+ if enum_from_base := base_field .data_type .find_source (Enum ): # pragma: no branch
1734+ return enum_from_base
1735+ return None
17311736
17321737 has_one_literal = False
17331738 for discriminator_field in discriminator_model .fields :
@@ -1759,7 +1764,9 @@ def get_discriminator_field_value(
17591764 discriminator_field .extras ["is_classvar" ] = True
17601765 break
17611766
1762- enum_source = discriminator_field .data_type .find_source (Enum ) or enum_from_base
1767+ enum_source = discriminator_field .data_type .find_source (Enum )
1768+ if self .use_enum_values_in_discriminator :
1769+ enum_source = enum_source or get_enum_from_base ()
17631770
17641771 for field_data_type in discriminator_field .data_type .all_data_types :
17651772 if field_data_type .reference : # pragma: no cover
@@ -1774,7 +1781,7 @@ def get_discriminator_field_value(
17741781 has_one_literal = True
17751782 if not has_one_literal :
17761783 new_data_type = self ._create_discriminator_data_type (
1777- enum_from_base , discriminator_values , discriminator_model , imports
1784+ get_enum_from_base () , discriminator_values , discriminator_model , imports
17781785 )
17791786 # Handle multiple aliases (Pydantic v2 AliasChoices)
17801787 single_alias : str | None = None
0 commit comments