Skip to content

Commit 1fc2087

Browse files
Avoid env_prefix falling back to env vars without prefix (#648)
Co-authored-by: Hasan Ramezani <[email protected]>
1 parent 0814553 commit 1fc2087

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

pydantic_settings/sources/providers/dotenv.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def __call__(self) -> dict[str, Any]:
109109
# As `extra` config is allowed in dotenv settings source, We have to
110110
# update data with extra env variables from dotenv file.
111111
for env_name, env_value in self.env_vars.items():
112-
if not env_value or env_name in data:
112+
if not env_value or env_name in data or (self.env_prefix and env_name in self.settings_cls.model_fields):
113113
continue
114114
env_used = False
115115
for field_name, field in self.settings_cls.model_fields.items():

tests/test_settings.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3000,6 +3000,61 @@ class Settings(BaseSettings):
30003000
assert s.model_dump() == {'foo': 'test-foo'}
30013001

30023002

3003+
def test_dotenv_env_prefix_env_without_prefix_ignored(tmp_path):
3004+
p = tmp_path / '.env'
3005+
p.write_text('foo=foo')
3006+
3007+
class Settings(BaseSettings):
3008+
model_config = SettingsConfigDict(
3009+
env_file=p,
3010+
env_prefix='TEST_',
3011+
extra='ignore',
3012+
)
3013+
3014+
foo: str = ''
3015+
3016+
s = Settings()
3017+
assert s.model_dump() == {'foo': ''}
3018+
3019+
3020+
def test_nested_model_dotenv_env_prefix_env_without_prefix_ignored(tmp_path):
3021+
p = tmp_path / '.env'
3022+
p.write_text('foo__val=1')
3023+
3024+
class Foo(BaseModel):
3025+
val: int = 0
3026+
3027+
class Settings(BaseSettings):
3028+
model_config = SettingsConfigDict(
3029+
env_nested_delimiter='__',
3030+
env_file=p,
3031+
env_prefix='TEST_',
3032+
extra='ignore',
3033+
)
3034+
3035+
foo: Foo = Foo()
3036+
3037+
s = Settings()
3038+
assert s.model_dump() == {'foo': {'val': 0}}
3039+
3040+
3041+
def test_dotenv_env_prefix_env_with_alias_without_prefix(tmp_path):
3042+
p = tmp_path / '.env'
3043+
p.write_text('FooAlias=foo')
3044+
3045+
class Settings(BaseSettings):
3046+
model_config = SettingsConfigDict(
3047+
env_file=p,
3048+
env_prefix='TEST_',
3049+
extra='ignore',
3050+
)
3051+
3052+
foo: str = Field('xxx', alias='FooAlias')
3053+
3054+
s = Settings()
3055+
assert s.model_dump() == {'foo': 'foo'}
3056+
3057+
30033058
def test_parsing_secret_field(env):
30043059
class Settings(BaseSettings):
30053060
foo: Secret[int]

0 commit comments

Comments
 (0)