SDK Version (required)
7.0.9
Describe the bug
UniversalBaseModel._coerce_field_names_to_aliases is a mode="before" model validator which makes it run for every nested model on each parsed object. Each call rebuilds name to alias maps which should be constant per class.
For v2 chat_stream this work runs multiple times per SSE event and can spend a large amount of parse time in this validator per event - I think this is the same class as the other caching fixes for _type_adapter_cache and _type_hints_cache in recent releases
Suggested fix
Cache per class, keyed like _type_adapter_cache:
- Compute once per class: the map of field names whose alias differs, plus the ambiguous-key set (key that is one field's alias and another's name)
- Fast paths - most models have no differing aliases and can be returned as is; if no field-name keys are present we can skip the dict copy
parse_obj_as's per-call has_pydantic_aliases scan asks the same question and can reuse the cache
Related to this - with caching parsing will still stay materially heavier than pydantic-core native behavior since the Fern-generated models seem to lean on smart unions instead of using a discriminator Pydantic can see
SDK Version (required)
7.0.9
Describe the bug
UniversalBaseModel._coerce_field_names_to_aliasesis amode="before"model validator which makes it run for every nested model on each parsed object. Each call rebuilds name to alias maps which should be constant per class.For
v2 chat_streamthis work runs multiple times per SSE event and can spend a large amount of parse time in this validator per event - I think this is the same class as the other caching fixes for _type_adapter_cache and _type_hints_cache in recent releasesSuggested fix
Cache per class, keyed like
_type_adapter_cache:parse_obj_as's per-callhas_pydantic_aliasesscan asks the same question and can reuse the cacheRelated to this - with caching parsing will still stay materially heavier than
pydantic-corenative behavior since the Fern-generated models seem to lean on smart unions instead of using a discriminator Pydantic can see