From 2d2f94f51f6f10d61334f0dbe257fc9664b75af3 Mon Sep 17 00:00:00 2001 From: Oliver Berger Date: Tue, 23 Apr 2024 14:09:33 +0200 Subject: [PATCH] fix: superfluous deep env conflicts with non-dict model leaf (#276) --- pydantic_settings/sources.py | 3 ++- tests/test_settings.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pydantic_settings/sources.py b/pydantic_settings/sources.py index 8bfd4f8b..9c2462ed 100644 --- a/pydantic_settings/sources.py +++ b/pydantic_settings/sources.py @@ -638,7 +638,8 @@ def explode_env_vars(self, field_name: str, field: FieldInfo, env_vars: Mapping[ except ValueError as e: if not allow_json_failure: raise e - env_var[last_key] = env_val + if isinstance(env_var, dict): + env_var[last_key] = env_val return result diff --git a/tests/test_settings.py b/tests/test_settings.py index 0fde5233..b2663cf0 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -2586,3 +2586,21 @@ class Settings(BaseSettings): env.set('sub_dict__bar__foo', '{"b": 2}') s = Settings() assert s.model_dump() == {'nested': {'foo': {'a': 1}}, 'sub_dict': {'bar': {'foo': {'b': 2}}}} + + +def test_nested_models_leaf_vs_deeper_env_dict_assumed(env): + class NestedSettings(BaseModel): + foo: str + + class Settings(BaseSettings): + model_config = SettingsConfigDict(env_nested_delimiter='__') + + nested: NestedSettings + + env.set('nested__foo', 'string') + env.set( + 'nested__foo__bar', + 'this should not be evaluated, since foo is a string by annotation and not a dict', + ) + s = Settings() + assert s.model_dump() == {'nested': {'foo': 'string'}}