Skip to content

Commit be78a03

Browse files
committed
Rename env_nested_depth to env_nested_max_split, default to None
1 parent b773f0d commit be78a03

File tree

5 files changed

+28
-27
lines changed

5 files changed

+28
-27
lines changed

docs/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ print(Settings().model_dump())
325325
`_env_nested_delimiter` keyword argument on instantiation.
326326

327327
By default environment variables are split by `env_nested_delimiter` into arbitrarily deep nested fields. You can limit
328-
the depth of the nested fields with the `env_nested_depth` config setting. A common use case this is particularly useful
328+
the depth of the nested fields with the `env_nested_max_split` config setting. A common use case this is particularly useful
329329
is for two-level deep settings, where the `env_nested_delimiter` (usually a single `_`) may be a substring of model
330330
field names. For example:
331331

@@ -353,7 +353,7 @@ class LLMConfig(BaseModel):
353353

354354
class GenerationConfig(BaseSettings):
355355
model_config = SettingsConfigDict(
356-
env_nested_delimiter='_', env_nested_depth=1, env_prefix='GENERATION_'
356+
env_nested_delimiter='_', env_nested_max_split=1, env_prefix='GENERATION_'
357357
)
358358

359359
llm: LLMConfig
@@ -373,7 +373,7 @@ print(GenerationConfig().model_dump())
373373
"""
374374
```
375375

376-
Without `env_nested_depth=1` set, `GENERATION_LLM_API_KEY` would be parsed as `llm.api.key` instead of `llm.api_key`
376+
Without `env_nested_max_split=1` set, `GENERATION_LLM_API_KEY` would be parsed as `llm.api.key` instead of `llm.api_key`
377377
and it would raise a `ValidationError`.
378378

379379
Nested environment variables take precedence over the top-level environment variable JSON

pydantic_settings/main.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class SettingsConfigDict(ConfigDict, total=False):
3838
env_file_encoding: str | None
3939
env_ignore_empty: bool
4040
env_nested_delimiter: str | None
41-
env_nested_depth: int
41+
env_nested_max_split: int | None
4242
env_parse_none_str: str | None
4343
env_parse_enums: bool | None
4444
cli_prog_name: str | None
@@ -113,7 +113,7 @@ class BaseSettings(BaseModel):
113113
_env_file_encoding: The env file encoding, e.g. `'latin-1'`. Defaults to `None`.
114114
_env_ignore_empty: Ignore environment variables where the value is an empty string. Default to `False`.
115115
_env_nested_delimiter: The nested env values delimiter. Defaults to `None`.
116-
_env_nested_depth: The nested env values maximum nesting. Defaults to `-1`, which means no limit.
116+
_env_nested_max_split: The nested env values maximum nesting. Defaults to `None`, which means no limit.
117117
_env_parse_none_str: The env string value that should be parsed (e.g. "null", "void", "None", etc.)
118118
into `None` type(None). Defaults to `None` type(None), which means no parsing should occur.
119119
_env_parse_enums: Parse enum field names to values. Defaults to `None.`, which means no parsing should occur.
@@ -150,7 +150,7 @@ def __init__(
150150
_env_file_encoding: str | None = None,
151151
_env_ignore_empty: bool | None = None,
152152
_env_nested_delimiter: str | None = None,
153-
_env_nested_depth: int | None = None,
153+
_env_nested_max_split: int | None = None,
154154
_env_parse_none_str: str | None = None,
155155
_env_parse_enums: bool | None = None,
156156
_cli_prog_name: str | None = None,
@@ -181,7 +181,7 @@ def __init__(
181181
_env_file_encoding=_env_file_encoding,
182182
_env_ignore_empty=_env_ignore_empty,
183183
_env_nested_delimiter=_env_nested_delimiter,
184-
_env_nested_depth=_env_nested_depth,
184+
_env_nested_max_split=_env_nested_max_split,
185185
_env_parse_none_str=_env_parse_none_str,
186186
_env_parse_enums=_env_parse_enums,
187187
_cli_prog_name=_cli_prog_name,
@@ -236,7 +236,7 @@ def _settings_build_values(
236236
_env_file_encoding: str | None = None,
237237
_env_ignore_empty: bool | None = None,
238238
_env_nested_delimiter: str | None = None,
239-
_env_nested_depth: int | None = None,
239+
_env_nested_max_split: int | None = None,
240240
_env_parse_none_str: str | None = None,
241241
_env_parse_enums: bool | None = None,
242242
_cli_prog_name: str | None = None,
@@ -275,8 +275,10 @@ def _settings_build_values(
275275
if _env_nested_delimiter is not None
276276
else self.model_config.get('env_nested_delimiter')
277277
)
278-
env_nested_depth = (
279-
_env_nested_depth if _env_nested_depth is not None else self.model_config.get('env_nested_depth')
278+
env_nested_max_split = (
279+
_env_nested_max_split
280+
if _env_nested_max_split is not None
281+
else self.model_config.get('env_nested_max_split')
280282
)
281283
env_parse_none_str = (
282284
_env_parse_none_str if _env_parse_none_str is not None else self.model_config.get('env_parse_none_str')
@@ -341,7 +343,7 @@ def _settings_build_values(
341343
case_sensitive=case_sensitive,
342344
env_prefix=env_prefix,
343345
env_nested_delimiter=env_nested_delimiter,
344-
env_nested_depth=env_nested_depth,
346+
env_nested_max_split=env_nested_max_split,
345347
env_ignore_empty=env_ignore_empty,
346348
env_parse_none_str=env_parse_none_str,
347349
env_parse_enums=env_parse_enums,
@@ -353,7 +355,7 @@ def _settings_build_values(
353355
case_sensitive=case_sensitive,
354356
env_prefix=env_prefix,
355357
env_nested_delimiter=env_nested_delimiter,
356-
env_nested_depth=env_nested_depth,
358+
env_nested_max_split=env_nested_max_split,
357359
env_ignore_empty=env_ignore_empty,
358360
env_parse_none_str=env_parse_none_str,
359361
env_parse_enums=env_parse_enums,
@@ -422,7 +424,7 @@ def _settings_build_values(
422424
env_file_encoding=None,
423425
env_ignore_empty=False,
424426
env_nested_delimiter=None,
425-
env_nested_depth=-1,
427+
env_nested_max_split=None,
426428
env_parse_none_str=None,
427429
env_parse_enums=None,
428430
cli_prog_name=None,

pydantic_settings/sources.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ def __init__(
735735
case_sensitive: bool | None = None,
736736
env_prefix: str | None = None,
737737
env_nested_delimiter: str | None = None,
738-
env_nested_depth: int | None = None,
738+
env_nested_max_split: int | None = None,
739739
env_ignore_empty: bool | None = None,
740740
env_parse_none_str: str | None = None,
741741
env_parse_enums: bool | None = None,
@@ -746,10 +746,10 @@ def __init__(
746746
self.env_nested_delimiter = (
747747
env_nested_delimiter if env_nested_delimiter is not None else self.config.get('env_nested_delimiter')
748748
)
749-
self.env_nested_depth = (
750-
env_nested_depth if env_nested_depth is not None else self.config.get('env_nested_depth', -1)
749+
self.env_nested_max_split = (
750+
env_nested_max_split if env_nested_max_split is not None else self.config.get('env_nested_max_split')
751751
)
752-
self.maxsplit = self.env_nested_depth - 1 if self.env_nested_depth > 0 else self.env_nested_depth
752+
self.maxsplit = (self.env_nested_max_split or 0) - 1
753753
self.env_prefix_len = len(self.env_prefix)
754754

755755
self.env_vars = self._load_env_vars()
@@ -954,7 +954,7 @@ def explode_env_vars(self, field_name: str, field: FieldInfo, env_vars: Mapping[
954954
def __repr__(self) -> str:
955955
return (
956956
f'{self.__class__.__name__}(env_nested_delimiter={self.env_nested_delimiter!r}, '
957-
f'env_nested_depth={self.env_nested_depth}, env_prefix_len={self.env_prefix_len!r})'
957+
f'env_prefix_len={self.env_prefix_len!r})'
958958
)
959959

960960

@@ -971,7 +971,7 @@ def __init__(
971971
case_sensitive: bool | None = None,
972972
env_prefix: str | None = None,
973973
env_nested_delimiter: str | None = None,
974-
env_nested_depth: int | None = None,
974+
env_nested_max_split: int | None = None,
975975
env_ignore_empty: bool | None = None,
976976
env_parse_none_str: str | None = None,
977977
env_parse_enums: bool | None = None,
@@ -985,7 +985,7 @@ def __init__(
985985
case_sensitive,
986986
env_prefix,
987987
env_nested_delimiter,
988-
env_nested_depth,
988+
env_nested_max_split,
989989
env_ignore_empty,
990990
env_parse_none_str,
991991
env_parse_enums,
@@ -1072,8 +1072,7 @@ def __call__(self) -> dict[str, Any]:
10721072
def __repr__(self) -> str:
10731073
return (
10741074
f'{self.__class__.__name__}(env_file={self.env_file!r}, env_file_encoding={self.env_file_encoding!r}, '
1075-
f'env_nested_delimiter={self.env_nested_delimiter!r}, env_nested_depth={self.env_nested_depth}, '
1076-
f'env_prefix_len={self.env_prefix_len!r})'
1075+
f'env_nested_delimiter={self.env_nested_delimiter!r}, env_prefix_len={self.env_prefix_len!r})'
10771076
)
10781077

10791078

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def docs_test_env():
7979
setenv.set('SUB_MODEL__V3', '3')
8080
setenv.set('SUB_MODEL__DEEP__V4', 'v4')
8181

82-
# envs for parsing environment variable values example with env_nested_depth=1
82+
# envs for parsing environment variable values example with env_nested_max_split=1
8383
setenv.set('GENERATION_LLM_PROVIDER', 'anthropic')
8484
setenv.set('GENERATION_LLM_API_KEY', 'your-api-key')
8585
setenv.set('GENERATION_LLM_API_VERSION', '2024-03-15')

tests/test_settings.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ class Cfg(BaseSettings):
399399

400400

401401
@pytest.mark.parametrize('env_prefix', [None, 'prefix_', 'prefix__'])
402-
def test_nested_env_depth(env, env_prefix):
402+
def test_nested_env_max_split(env, env_prefix):
403403
class Person(BaseModel):
404404
sex: Literal['M', 'F']
405405
first_name: str
@@ -410,7 +410,7 @@ class Cfg(BaseSettings):
410410
significant_other: Optional[Person] = None
411411
next_of_kin: Optional[Person] = None
412412

413-
model_config = SettingsConfigDict(env_nested_delimiter='_', env_nested_depth=1)
413+
model_config = SettingsConfigDict(env_nested_delimiter='_', env_nested_max_split=1)
414414
if env_prefix is not None:
415415
model_config['env_prefix'] = env_prefix
416416

@@ -1857,11 +1857,11 @@ def test_builtins_settings_source_repr():
18571857
)
18581858
assert (
18591859
repr(EnvSettingsSource(BaseSettings, env_nested_delimiter='__'))
1860-
== "EnvSettingsSource(env_nested_delimiter='__', env_nested_depth=-1, env_prefix_len=0)"
1860+
== "EnvSettingsSource(env_nested_delimiter='__', env_prefix_len=0)"
18611861
)
18621862
assert repr(DotEnvSettingsSource(BaseSettings, env_file='.env', env_file_encoding='utf-8')) == (
18631863
"DotEnvSettingsSource(env_file='.env', env_file_encoding='utf-8', "
1864-
'env_nested_delimiter=None, env_nested_depth=-1, env_prefix_len=0)'
1864+
'env_nested_delimiter=None, env_prefix_len=0)'
18651865
)
18661866
assert (
18671867
repr(SecretsSettingsSource(BaseSettings, secrets_dir='/secrets'))

0 commit comments

Comments
 (0)