Skip to content

CLI use of IntEnum not working with nested models #583

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lsg551 opened this issue Apr 10, 2025 · 4 comments · Fixed by #589
Closed

CLI use of IntEnum not working with nested models #583

lsg551 opened this issue Apr 10, 2025 · 4 comments · Fixed by #589
Labels
bug Something isn't working

Comments

@lsg551
Copy link

lsg551 commented Apr 10, 2025

Description

The pydantic docs about the usage of enums in CLIs state that enum.IntEnum can perfectly be used with CLIs, where the enum's field names are eventually accepted as flag values.

[excerpt] from the docs:

CLI argument parsing of literals and enums are converted into CLI choices.

import sys
from enum import IntEnum
from pydantic_settings import BaseSettings

class Fruit(IntEnum):
    pear = 0
    kiwi = 1
    lime = 2

class Settings(BaseSettings, cli_parse_args=True):
    fruit: Fruit

sys.argv = ['example.py', '--fruit', 'lime']
print(Settings().model_dump())
#> {'fruit': <Fruit.lime: 2>}

And this works totally fine. But as soon as a model is nested, it raises a validation error. For example, consider this scenario:

from enum import IntEnum

class LogLevel(IntEnum):
    CRITICAL = 50
    ERROR = 40
    WARNING = 30
    INFO = 20
    DEBUG = 10

@pydantic.dataclasses.dataclass
class LoggingOptions:
    level: LogLevel = LogLevel.INFO

class Settings(BaseSettings):

    model_config = SettingsConfigDict(
        cli_parse_args=True,
        cli_kebab_case=True,
        cli_use_class_docs_for_groups=True,
        cli_avoid_json=True,
        frozen=True,
    )

    level: LogLevel = LogLevel.INFO # this works

    logging: LoggingOptions # this DOES NOT work

When tested, the root level flags work as intended with integer enums:

 sys.argv = ['example.py', '--level', 'DEBUG']
 settings = Settings()

However, nested ones do not:

 sys.argv = ['example.py', '--logging.level', 'DEBUG']
 settings = Settings()

and this will raise:

Traceback (most recent call last):
  File "/project/sandbox/main.py", line 55, in <module>
    settings = Settings()
               ^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/pydantic_settings/main.py", line 176, in __init__
    super().__init__(
  File "/usr/local/lib/python3.12/site-packages/pydantic/main.py", line 253, in __init__
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 1 validation error for Settings
logging.level
  Input should be 50, 50, 40, 30, 30, 20, 10 or 0 [type=enum, input_value='DEBUG', input_type=str]
    For further information visit https://errors.pydantic.dev/2.11/v/enum

Expected Behaviour

I expected this to work properly with nested models too, just like root level objects. However, I am not familiar enough with pydantic or pydantic-settings to tell whether this is intended / expected behaviour.

I searched the docs and issues, but couldn't find related information. Sorry, if this was already brought up.

How to replicate

Note that the code of the above examples is simplified, but I created a codesandbox to replicate this: https://codesandbox.io/p/devbox/59rv9y?embed=1&file=%2Fmain.py

Affected Versions

I tested with the latest versions of pydantic and pydantic-settings:

  • pydantic == 2.11.3
  • pydantic-settings == 2.8.1

and used Python 3.12 as well as 3.13.

@hramezani
Copy link
Member

@kschwab please take a look when you have time. sorry for pinging you too much, you are the only person who is expert in CLI.

@kschwab
Copy link
Contributor

kschwab commented Apr 14, 2025

No worries @hramezani, happy to help. Opened #589 for resolution.

@hramezani hramezani added bug Something isn't working and removed unconfirmed labels Apr 14, 2025
@hramezani
Copy link
Member

Thanks @kschwab for the fix PR and sorry for asking you to fix a non cli bug.

@lsg551
Copy link
Author

lsg551 commented Apr 15, 2025

Greatly appreciate that, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants