Skip to content

Commit 6232d4d

Browse files
committed
test multi-source validation
and include missing fields
1 parent 38e94de commit 6232d4d

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

tests/test_multi_source.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"""
2+
Integration tests with multiple sources
3+
"""
4+
5+
from typing import Tuple, Type, Union
6+
7+
from pydantic import BaseModel, ValidationError
8+
import pytest
9+
10+
from pydantic_settings import (
11+
BaseSettings,
12+
JsonConfigSettingsSource,
13+
PydanticBaseSettingsSource,
14+
SettingsConfigDict,
15+
)
16+
17+
def test_line_errors_from_source(monkeypatch, tmp_path):
18+
monkeypatch.setenv("SETTINGS_NESTED__NESTED_FIELD", "a")
19+
p = tmp_path / 'settings.json'
20+
p.write_text(
21+
"""
22+
{"foobar": 0, "null_field": null}
23+
"""
24+
)
25+
26+
class Nested(BaseModel):
27+
nested_field: int
28+
29+
class Settings(BaseSettings):
30+
model_config = SettingsConfigDict(
31+
json_file=p,
32+
env_prefix="SETTINGS_",
33+
env_nested_delimiter="__",
34+
validate_each_source=True
35+
)
36+
foobar: str
37+
nested: Nested
38+
null_field: Union[str, None]
39+
extra: bool
40+
41+
@classmethod
42+
def settings_customise_sources(
43+
cls,
44+
settings_cls: Type[BaseSettings],
45+
init_settings: PydanticBaseSettingsSource,
46+
env_settings: PydanticBaseSettingsSource,
47+
dotenv_settings: PydanticBaseSettingsSource,
48+
file_secret_settings: PydanticBaseSettingsSource,
49+
) -> Tuple[PydanticBaseSettingsSource, ...]:
50+
return (
51+
JsonConfigSettingsSource(settings_cls),
52+
env_settings,
53+
init_settings
54+
)
55+
56+
with pytest.raises(ValidationError) as exc_info:
57+
_ = Settings(null_field=0)
58+
59+
assert exc_info.value.errors(include_url=False) == [
60+
{
61+
'ctx': {'source': 'JsonConfigSettingsSource'},
62+
'input': 0,
63+
'loc': ('foobar',),
64+
'msg': 'Input should be a valid string',
65+
'type': 'string_type',
66+
},
67+
{
68+
'ctx': {'source': 'EnvSettingsSource'},
69+
'input': 'a',
70+
'loc': ('nested', 'nested_field'),
71+
'msg': 'Input should be a valid integer, unable to parse string as an integer',
72+
'type': 'int_parsing'
73+
},
74+
{
75+
'ctx': {'source': 'InitSettingsSource'},
76+
'input': 0,
77+
'loc': ('null_field',),
78+
'msg': 'Input should be a valid string',
79+
'type': 'string_type'
80+
},
81+
{
82+
'input': {'foobar': 0, 'nested': {'nested_field': 'a'}, 'null_field': None},
83+
'loc': ('extra',),
84+
'msg': 'Field required',
85+
'type': 'missing'
86+
}
87+
]

0 commit comments

Comments
 (0)