From d611ff6e826ea49d316ee915d52548880565a68d Mon Sep 17 00:00:00 2001 From: Kyle Schwab Date: Tue, 2 Jan 2024 16:27:34 -0700 Subject: [PATCH 1/2] Allow nested env var source to override nested init source. --- pydantic_settings/sources.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydantic_settings/sources.py b/pydantic_settings/sources.py index 28178f03..fc7bba93 100644 --- a/pydantic_settings/sources.py +++ b/pydantic_settings/sources.py @@ -10,7 +10,7 @@ from typing import TYPE_CHECKING, Any, List, Mapping, Sequence, Tuple, Union, cast from dotenv import dotenv_values -from pydantic import AliasChoices, AliasPath, BaseModel, Json +from pydantic import AliasChoices, AliasPath, BaseModel, Json, TypeAdapter from pydantic._internal._typing_extra import origin_is_union from pydantic._internal._utils import deep_update, lenient_issubclass from pydantic.fields import FieldInfo @@ -121,7 +121,7 @@ def get_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str, return None, '', False def __call__(self) -> dict[str, Any]: - return self.init_kwargs + return TypeAdapter(dict[str, Any]).dump_python(self.init_kwargs) def __repr__(self) -> str: return f'InitSettingsSource(init_kwargs={self.init_kwargs!r})' From 5519fd6f96d0d162652a9b23648973af238613ab Mon Sep 17 00:00:00 2001 From: Kyle Schwab Date: Thu, 4 Jan 2024 21:12:07 -0700 Subject: [PATCH 2/2] Add test. --- pydantic_settings/sources.py | 4 ++-- tests/test_settings.py | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/pydantic_settings/sources.py b/pydantic_settings/sources.py index fc7bba93..7af1f487 100644 --- a/pydantic_settings/sources.py +++ b/pydantic_settings/sources.py @@ -7,7 +7,7 @@ from collections import deque from dataclasses import is_dataclass from pathlib import Path -from typing import TYPE_CHECKING, Any, List, Mapping, Sequence, Tuple, Union, cast +from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Sequence, Tuple, Union, cast from dotenv import dotenv_values from pydantic import AliasChoices, AliasPath, BaseModel, Json, TypeAdapter @@ -121,7 +121,7 @@ def get_field_value(self, field: FieldInfo, field_name: str) -> tuple[Any, str, return None, '', False def __call__(self) -> dict[str, Any]: - return TypeAdapter(dict[str, Any]).dump_python(self.init_kwargs) + return TypeAdapter(Dict[str, Any]).dump_python(self.init_kwargs) def __repr__(self) -> str: return f'InitSettingsSource(init_kwargs={self.init_kwargs!r})' diff --git a/tests/test_settings.py b/tests/test_settings.py index 9a7fe697..36dcc7e4 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -619,6 +619,43 @@ def settings_customise_sources( assert s.bar == 'env setting' +def test_env_deep_override(env): + class DeepSubModel(BaseModel): + v4: str + + class SubModel(BaseModel): + v1: str + v2: bytes + v3: int + deep: DeepSubModel + + class Settings(BaseSettings, env_nested_delimiter='__'): + v0: str + sub_model: SubModel + + @classmethod + def settings_customise_sources( + cls, settings_cls, init_settings, env_settings, dotenv_settings, file_secret_settings + ): + return env_settings, dotenv_settings, init_settings, file_secret_settings + + env.set('SUB_MODEL__DEEP__V4', 'override-v4') + + s_final = {'v0': '0', 'sub_model': {'v1': 'init-v1', 'v2': b'init-v2', 'v3': 3, 'deep': {'v4': 'override-v4'}}} + + s = Settings(v0='0', sub_model={'v1': 'init-v1', 'v2': b'init-v2', 'v3': 3, 'deep': {'v4': 'init-v4'}}) + assert s.model_dump() == s_final + + s = Settings(v0='0', sub_model=SubModel(v1='init-v1', v2=b'init-v2', v3=3, deep=DeepSubModel(v4='init-v4'))) + assert s.model_dump() == s_final + + s = Settings(v0='0', sub_model=SubModel(v1='init-v1', v2=b'init-v2', v3=3, deep={'v4': 'init-v4'})) + assert s.model_dump() == s_final + + s = Settings(v0='0', sub_model={'v1': 'init-v1', 'v2': b'init-v2', 'v3': 3, 'deep': DeepSubModel(v4='init-v4')}) + assert s.model_dump() == s_final + + def test_config_file_settings_nornir(env): """ See https://github.com/pydantic/pydantic/pull/341#issuecomment-450378771