@@ -189,9 +189,24 @@ def _process_attribute(attr: Attribute, cls: Class, *, processed: set[str]) -> N
189189 attr .labels .discard ("instance-attribute" )
190190
191191 attr .value = kwargs .get ("default" )
192- constraints = {kwarg : value for kwarg , value in kwargs .items () if kwarg not in {"default" , "description" }}
192+ constraints = {
193+ kwarg : value
194+ for kwarg , value in kwargs .items ()
195+ if kwarg not in {"default" , "description" , "serialization_alias" }
196+ }
193197 attr .extra [common ._self_namespace ]["constraints" ] = constraints
194198
199+ # Store serialization_alias if present
200+ if serialization_alias := kwargs .get ("serialization_alias" ):
201+ if isinstance (serialization_alias , str ):
202+ try :
203+ attr .extra [common ._self_namespace ]["serialization_alias" ] = ast .literal_eval (serialization_alias )
204+ except ValueError :
205+ attr .extra [common ._self_namespace ]["serialization_alias" ] = serialization_alias
206+ elif isinstance (serialization_alias , (ExprName , Expr )):
207+ # For now, we can't resolve expressions at static analysis time
208+ _logger .debug (f"Could not resolve serialization_alias expression for field '{ attr .path } '" )
209+
195210 # Populate docstring from the field's `description` argument.
196211 if not attr .docstring and (description_expr := kwargs .get ("description" )):
197212 if description_text := _extract_description (description_expr ):
@@ -215,7 +230,7 @@ def _process_function(func: Function, cls: Class, *, processed: set[str]) -> Non
215230 common ._process_function (func , cls , fields )
216231
217232
218- def _process_class (cls : Class , * , processed : set [str ], schema : bool = False ) -> None :
233+ def _process_class (cls : Class , * , processed : set [str ], schema : bool = False , serialize_by_alias : bool = False ) -> None :
219234 """Finalize the Pydantic model data."""
220235 if cls .canonical_path in processed :
221236 return
@@ -225,7 +240,7 @@ def _process_class(cls: Class, *, processed: set[str], schema: bool = False) ->
225240
226241 processed .add (cls .canonical_path )
227242
228- common ._process_class (cls )
243+ common ._process_class (cls , serialize_by_alias = serialize_by_alias )
229244
230245 if schema :
231246 import_path : Path | list [Path ] = cls .package .filepath
@@ -240,7 +255,9 @@ def _process_class(cls: Class, *, processed: set[str], schema: bool = False) ->
240255 _logger .debug (f"Could not import class { cls .path } for JSON schema" )
241256 return
242257 try :
243- cls .extra [common ._self_namespace ]["schema" ] = common ._json_schema (true_class )
258+ cls .extra [common ._self_namespace ]["schema" ] = common ._json_schema (
259+ true_class ,
260+ )
244261 except Exception as exc : # noqa: BLE001
245262 # Schema generation can fail and raise Pydantic errors.
246263 _logger .debug ("Failed to generate schema for %s: %s" , cls .path , exc )
@@ -252,14 +269,15 @@ def _process_class(cls: Class, *, processed: set[str], schema: bool = False) ->
252269 elif kind is Kind .FUNCTION :
253270 _process_function (member , cls , processed = processed ) # ty: ignore[invalid-argument-type]
254271 elif kind is Kind .CLASS :
255- _process_class (member , processed = processed , schema = schema ) # ty: ignore[invalid-argument-type]
272+ _process_class (member , processed = processed , schema = schema , serialize_by_alias = serialize_by_alias ) # ty: ignore[invalid-argument-type]
256273
257274
258275def _process_module (
259276 mod : Module ,
260277 * ,
261278 processed : set [str ],
262279 schema : bool = False ,
280+ serialize_by_alias : bool = False ,
263281) -> None :
264282 """Handle Pydantic models in a module."""
265283 if mod .canonical_path in processed :
@@ -269,9 +287,9 @@ def _process_module(
269287 for cls in mod .classes .values ():
270288 # Don't process aliases, real classes will be processed at some point anyway.
271289 if not cls .is_alias :
272- _process_class (cls , processed = processed , schema = schema )
290+ _process_class (cls , processed = processed , schema = schema , serialize_by_alias = serialize_by_alias )
273291
274292 for submodule in mod .modules .values ():
275293 # Same for modules, don't process aliased ones.
276294 if not submodule .is_alias :
277- _process_module (submodule , processed = processed , schema = schema )
295+ _process_module (submodule , processed = processed , schema = schema , serialize_by_alias = serialize_by_alias )
0 commit comments