Deserialize field by alias instead of name
As per #76 (closed), Typed Settings should deserialize by field alias:
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.
This PR adds this behavior and also adds tests to verify correctness. Important things to note:
- Dataclasses do not natively support aliases, so it continues to deserialize by field name.
- attrs always populates
alias, but Pydantic does not. - Pydantic aliases also support
AliasPathandAliasChoicesin addtion tostr; this PR takes the easy path of falling back to the field name when the field alias is not astr(otherwise the logic to handleAliasPathandAliasChoiceswould be quite complex and may even require a refactor). - This is technically a breaking change (although I expect most people will not have set aliases for their settings classes given that (a) they did not work previously when loading from a file or environment variables and (b) instantiating a settings class with its
__init__method seems like it would be a rare occurence) and should be noted as such in the changelog.
In addtion, this PR fixes a few type hinting bugs:
- The type hint for
config_file_section(used inload()anddefault_loaders()) now correctly acceptsNone(which allFileFormats already accept). - The type signature of
structure()in theConverterprotocol is changed fromdef structure(self, value: Any, cls: type[T]) -> T:todef structure(self, obj: Any, cl: type[T]) -> T:. This correctly allows thecattrsConverterto implement the protocol as the parameter names need to be identical to do so.
Fixes #76 (closed).
Edited by Seow Alex