fix: parse enum names through nested annotations - #910
Conversation
Walk nested annotation arguments when resolving enum member names. Add a regression test for an optional Annotated enum.
Cast the leniently validated enum candidate before member lookup so the strict mypy gate accepts the recursive annotation fix.
_annotation_enum_val_to_name had the same one-level limitation that was
just fixed in _annotation_enum_name_to_val: it only inspected the
annotation, its origin, and its direct args, so an enum wrapped as
Optional[Annotated[MyEnum, ...]] was not resolved. This affected CLI
help rendering of enum defaults, which fell back to the raw value
(e.g. "(default: 1)") instead of the member name ("(default: kiwi)").
Resolve enum members recursively through annotation arguments, mirroring
the name_to_val fix. Regression test fails before the source change and
passes with it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks @Sanjays2402 for the fix! I pushed one follow-up commit (
The commit applies the same recursive-descent pattern you used for |
There was a problem hiding this comment.
Pull request overview
Fixes enum parsing when env_parse_enums=True (and CLI default rendering) for enums wrapped inside nested typing constructs (e.g. Optional[Annotated[MyEnum, ...]]), by recursively inspecting annotation arguments to resolve enum names/values correctly.
Changes:
- Update enum (name ↔ value) resolution helpers to traverse nested annotation arguments recursively.
- Add a regression test ensuring CLI
--helpshows enum defaults correctly through nestedAnnotated+ optional wrappers. - Add a regression test ensuring env enum parsing works through nested
Annotated+ optional wrappers.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tests/test_source_cli.py | Adds CLI help-output regression test for enum defaults in nested annotations. |
| tests/test_settings.py | Adds env parsing regression test for enums in nested Annotated + optional annotations. |
| pydantic_settings/sources/utils.py | Makes enum name/value resolution recursive across annotation arguments to support nested wrappers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks @Sanjays2402 |
With
env_parse_enums=True, enum names inside nested wrappers such asOptional[Annotated[MyEnum, ...]]were left as strings and failed validation. Resolve enum members recursively through annotation arguments, while preserving existing direct and union handling; the regression test fails before the source change and passes with it.