Skip to content

Performance: _coerce_field_names_to_aliases rebuilds on each validation and can block streaming CPU #802

Description

@keatingw

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions