diff --git a/pydantic_settings/sources/providers/env.py b/pydantic_settings/sources/providers/env.py index 5ab05378..5a350f1d 100644 --- a/pydantic_settings/sources/providers/env.py +++ b/pydantic_settings/sources/providers/env.py @@ -242,6 +242,9 @@ def explode_env_vars(self, field_name: str, field: FieldInfo, env_vars: Mapping[ if (target_field or is_dict) and env_val: if target_field: is_complex, allow_json_failure = self._field_is_complex(target_field) + if self.env_parse_enums: + enum_val = _annotation_enum_name_to_val(target_field.annotation, env_val) + env_val = env_val if enum_val is None else enum_val else: # nested field type is dict is_complex, allow_json_failure = True, True diff --git a/tests/test_settings.py b/tests/test_settings.py index 5ca14d85..1800d544 100644 --- a/tests/test_settings.py +++ b/tests/test_settings.py @@ -2348,13 +2348,18 @@ class Settings(BaseSettings): def test_env_parse_enums(env): - class Settings(BaseSettings): + class NestedEnum(BaseModel): + fruit: FruitsEnum + + class Settings(BaseSettings, env_nested_delimiter='__'): fruit: FruitsEnum union_fruit: Optional[Union[int, FruitsEnum]] = None + nested: NestedEnum with pytest.raises(ValidationError) as exc_info: env.set('FRUIT', 'kiwi') env.set('UNION_FRUIT', 'kiwi') + env.set('NESTED__FRUIT', 'kiwi') s = Settings() assert exc_info.value.errors(include_url=False) == [ { @@ -2385,22 +2390,43 @@ class Settings(BaseSettings): 'msg': 'Input should be 0, 1 or 2', 'type': 'enum', }, + { + 'ctx': { + 'expected': '0, 1 or 2', + }, + 'input': 'kiwi', + 'loc': ( + 'nested', + 'fruit', + ), + 'msg': 'Input should be 0, 1 or 2', + 'type': 'enum', + }, ] env.set('FRUIT', str(FruitsEnum.lime.value)) env.set('UNION_FRUIT', str(FruitsEnum.lime.value)) + env.set('NESTED__FRUIT', str(FruitsEnum.lime.value)) s = Settings() assert s.fruit == FruitsEnum.lime + assert s.union_fruit == FruitsEnum.lime + assert s.nested.fruit == FruitsEnum.lime env.set('FRUIT', 'kiwi') env.set('UNION_FRUIT', 'kiwi') + env.set('NESTED__FRUIT', 'kiwi') s = Settings(_env_parse_enums=True) assert s.fruit == FruitsEnum.kiwi + assert s.union_fruit == FruitsEnum.kiwi + assert s.nested.fruit == FruitsEnum.kiwi env.set('FRUIT', str(FruitsEnum.lime.value)) env.set('UNION_FRUIT', str(FruitsEnum.lime.value)) + env.set('NESTED__FRUIT', str(FruitsEnum.lime.value)) s = Settings(_env_parse_enums=True) assert s.fruit == FruitsEnum.lime + assert s.union_fruit == FruitsEnum.lime + assert s.nested.fruit == FruitsEnum.lime def test_env_parse_none_str(env):