Skip to content

Field alias should be preferred over name

Currently, settings are deserialised by field name. A few examples:

However, I believe the correct behaviour should be deserialising by field alias (which attrs and Pydantic seem to support):

attrs

alias (str | None) – Override this attribute’s parameter name in the generated __init__ method.

Pydantic

An alias is an alternative name for a field, used when serializing and deserializing data.

For my specific use case, I have several uppercase attributes that I would like to deserialise from lowercase keys (for e.g., deserialising PROJECT_DIR from project-dir), which I achieve with a field_transformer that automatically sets lowercase aliases for fields:

@frozen(
    field_transformer=lambda _, fields: [
        field.evolve(alias=field.name.lower()) for field in fields
    ]
)
class Settings:
    ...

However, this does not work with typed-settings, since it uses field names.

Several considerations I am thinking about:

  1. This change should (largely) be backwards compatible, since I believe both attrs and Pydantic default to aliases that are identical to the field names (although attrs does strip leading underscores).
  2. Dataclasses do not seem to natively support aliases, and so there would be a difference in logic between dataclasses and attrs/Pydantic.
  3. The cattrs converter does not use aliases by default, but this can be set in the converter as of v25.2.0, or using a structure hook factory in earlier versions.
  4. Pydantic aliases can be a str, AliasPath, or AliasChoices. This may complicate the implementation (although perhaps we should only support str?).
Edited by Seow Alex