@@ -225,7 +225,7 @@ class FieldNameResolver:
225225
226226 def __init__ ( # noqa: PLR0913, PLR0917
227227 self ,
228- aliases : Mapping [str , str ] | None = None ,
228+ aliases : Mapping [str , str | list [ str ] ] | None = None ,
229229 snake_case_field : bool = False , # noqa: FBT001, FBT002
230230 empty_field_name : str | None = None ,
231231 original_delimiter : str | None = None ,
@@ -235,7 +235,7 @@ def __init__( # noqa: PLR0913, PLR0917
235235 no_alias : bool = False , # noqa: FBT001, FBT002
236236 ) -> None :
237237 """Initialize field name resolver with transformation options."""
238- self .aliases : Mapping [str , str ] = {} if aliases is None else {** aliases }
238+ self .aliases : Mapping [str , str | list [ str ] ] = {} if aliases is None else {** aliases }
239239 self .empty_field_name : str = empty_field_name or "_"
240240 self .snake_case_field = snake_case_field
241241 self .original_delimiter : str | None = original_delimiter
@@ -306,7 +306,7 @@ def get_valid_field_name_and_alias(
306306 excludes : set [str ] | None = None ,
307307 path : list [str ] | None = None ,
308308 class_name : str | None = None ,
309- ) -> tuple [str , str | None ]:
309+ ) -> tuple [str , str | list [ str ] | None ]:
310310 """Get valid field name and original alias if different.
311311
312312 Supports hierarchical alias resolution with the following priority:
@@ -318,15 +318,33 @@ def get_valid_field_name_and_alias(
318318 excludes: Set of names to avoid when generating valid names.
319319 path: Unused, kept for backward compatibility.
320320 class_name: Optional class name for scoped alias resolution.
321+
322+ Returns:
323+ A tuple of (python_field_name, alias_or_aliases) where:
324+ - python_field_name: The valid Python identifier to use as the field name.
325+ - alias_or_aliases: None if no alias needed, str for single alias,
326+ or list[str] for multiple aliases (Pydantic v2 AliasChoices).
321327 """
322328 del path
323329 if class_name :
324330 scoped_key = f"{ class_name } .{ field_name } "
325331 if scoped_key in self .aliases :
326- return self .aliases [scoped_key ], field_name
332+ alias_value = self .aliases [scoped_key ]
333+ if isinstance (alias_value , list ) and alias_value :
334+ # Multiple aliases: validate first alias as field name, return all aliases including original
335+ valid_name = self .get_valid_name (alias_value [0 ], excludes = excludes )
336+ return valid_name , [field_name , * alias_value ]
337+ if isinstance (alias_value , str ):
338+ return alias_value , field_name
327339
328340 if field_name in self .aliases :
329- return self .aliases [field_name ], field_name
341+ alias_value = self .aliases [field_name ]
342+ if isinstance (alias_value , list ) and alias_value :
343+ # Multiple aliases: validate first alias as field name, return all aliases including original
344+ valid_name = self .get_valid_name (alias_value [0 ], excludes = excludes )
345+ return valid_name , [field_name , * alias_value ]
346+ if isinstance (alias_value , str ):
347+ return alias_value , field_name
330348
331349 valid_name = self .get_valid_name (field_name , excludes = excludes )
332350 return (
@@ -1064,7 +1082,7 @@ def get_valid_field_name_and_alias(
10641082 model_type : ModelType = ModelType .PYDANTIC ,
10651083 path : list [str ] | None = None ,
10661084 class_name : str | None = None ,
1067- ) -> tuple [str , str | None ]:
1085+ ) -> tuple [str , str | list [ str ] | None ]:
10681086 """Get a valid field name and alias for the specified model type.
10691087
10701088 Args:
@@ -1075,7 +1093,10 @@ def get_valid_field_name_and_alias(
10751093 class_name: Optional class name for scoped alias resolution.
10761094
10771095 Returns:
1078- A tuple of (valid_field_name, alias_or_none).
1096+ A tuple of (python_field_name, alias_or_aliases) where:
1097+ - python_field_name: The valid Python identifier to use as the field name.
1098+ - alias_or_aliases: None if no alias needed, str for single alias,
1099+ or list[str] for multiple aliases (Pydantic v2 AliasChoices).
10791100 """
10801101 del path
10811102 return self .field_name_resolvers [model_type ].get_valid_field_name_and_alias (
0 commit comments