diff --git a/pydantic_settings/sources.py b/pydantic_settings/sources.py index bd4f4315..cfbbac08 100644 --- a/pydantic_settings/sources.py +++ b/pydantic_settings/sources.py @@ -388,7 +388,17 @@ def __init__( init_kwargs: dict[str, Any], nested_model_default_partial_update: bool | None = None, ): - self.init_kwargs = init_kwargs + self.init_kwargs = {} + init_kwarg_names = set(init_kwargs.keys()) + for field_name, field_info in settings_cls.model_fields.items(): + alias_names, *_ = _get_alias_names(field_name, field_info) + init_kwarg_name = init_kwarg_names & set(alias_names) + if init_kwarg_name: + preferred_alias = alias_names[0] + init_kwarg_names -= init_kwarg_name + self.init_kwargs[preferred_alias] = init_kwargs[init_kwarg_name.pop()] + self.init_kwargs.update({key: val for key, val in init_kwargs.items() if key in init_kwarg_names}) + super().__init__(settings_cls) self.nested_model_default_partial_update = ( nested_model_default_partial_update diff --git a/tests/test_settings.py b/tests/test_settings.py index ba793a8e..1483dd7d 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -662,6 +662,17 @@ def settings_customise_sources( assert s.model_dump() == s_final +def test_alias_resolution_init_source(env): + class Example(BaseSettings): + model_config = SettingsConfigDict(env_prefix='PREFIX') + + name: str + last_name: str = Field(validation_alias=AliasChoices('PREFIX_LAST_NAME', 'PREFIX_SURNAME')) + + env.set('PREFIX_SURNAME', 'smith') + assert Example(name='john', PREFIX_SURNAME='doe').model_dump() == {'name': 'john', 'last_name': 'doe'} + + def test_alias_nested_model_default_partial_update(): class SubModel(BaseModel): v1: str = 'default'