Skip to content

Commit 4d2ebfd

Browse files
authored
Strip non-explicit default values. (#692)
1 parent 4a6ffca commit 4d2ebfd

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

pydantic_settings/main.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ def _settings_build_values(
426426

427427
if sources:
428428
state: dict[str, Any] = {}
429+
defaults: dict[str, Any] = {}
429430
states: dict[str, dict[str, Any]] = {}
430431
for source in sources:
431432
if isinstance(source, PydanticBaseSettingsSource):
@@ -435,8 +436,15 @@ def _settings_build_values(
435436
source_name = source.__name__ if hasattr(source, '__name__') else type(source).__name__
436437
source_state = source()
437438

439+
if isinstance(source, DefaultSettingsSource):
440+
defaults = source_state
441+
438442
states[source_name] = source_state
439443
state = deep_update(source_state, state)
444+
445+
# Strip any default values not explicity set before returning final state
446+
state = {key: val for key, val in state.items() if key not in defaults or defaults[key] != val}
447+
440448
return state
441449
else:
442450
# no one should mean to do this, but I think returning an empty dict is marginally preferable

tests/test_settings.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,8 +639,27 @@ class SettingsDefaultsA(BaseSettings, env_nested_delimiter='__', nested_model_de
639639
nested_d: NestedC = NestedC(v0=False, v1=True)
640640
nested_c: NestedD = NestedD()
641641

642+
assert SettingsDefaultsA().model_dump() == {
643+
'nested_a': {'v0': False, 'v1': True},
644+
'nested_b': {'v0': False, 'v1': True},
645+
'nested_c': {'v0': False, 'v1': True},
646+
'nested_d': {'v0': False, 'v1': True},
647+
}
648+
assert SettingsDefaultsA().model_dump(exclude_unset=True) == {}
649+
642650
env.set('NESTED_A__V0', 'True')
643651
env.set('NESTED_B__V0', 'True')
652+
assert SettingsDefaultsA().model_dump() == {
653+
'nested_a': {'v0': True, 'v1': True},
654+
'nested_b': {'v0': True, 'v1': True},
655+
'nested_c': {'v0': False, 'v1': True},
656+
'nested_d': {'v0': False, 'v1': True},
657+
}
658+
assert SettingsDefaultsA().model_dump(exclude_unset=True) == {
659+
'nested_a': {'v0': True, 'v1': True},
660+
'nested_b': {'v0': True, 'v1': True},
661+
}
662+
644663
env.set('NESTED_C__V0', 'True')
645664
env.set('NESTED_D__V0', 'True')
646665
assert SettingsDefaultsA().model_dump() == {
@@ -649,6 +668,12 @@ class SettingsDefaultsA(BaseSettings, env_nested_delimiter='__', nested_model_de
649668
'nested_c': {'v0': True, 'v1': True},
650669
'nested_d': {'v0': True, 'v1': True},
651670
}
671+
assert SettingsDefaultsA().model_dump(exclude_unset=True) == {
672+
'nested_a': {'v0': True, 'v1': True},
673+
'nested_b': {'v0': True, 'v1': True},
674+
'nested_c': {'v0': True, 'v1': True},
675+
'nested_d': {'v0': True, 'v1': True},
676+
}
652677

653678

654679
def test_init_kwargs_nested_model_default_partial_update(env):

0 commit comments

Comments
 (0)