Skip to content

Unexpected behaviour in CliSettingsSource when cli_parse_args=True in model_config #610

@trygve-baerland

Description

@trygve-baerland

Suppose I want to create a simple CLI tool, where the only allowed source is from the command line.
Something along the lines of:

import sys

from pydantic_settings import (
    BaseSettings,
    CliSettingsSource,
    PydanticBaseSettingsSource,
    SettingsConfigDict,
)


class Settings(BaseSettings):
    model_config = SettingsConfigDict(cli_parse_args=True)

    value: int

    @classmethod
    def settings_customise_sources(
        cls,
        settings_cls: type[BaseSettings],
        init_settings: PydanticBaseSettingsSource,
        env_settings: PydanticBaseSettingsSource,
        dotenv_settings: PydanticBaseSettingsSource,
        file_secret_settings: PydanticBaseSettingsSource,
    ) -> tuple[PydanticBaseSettingsSource, ...]:
        """Set up config priority."""
        return (CliSettingsSource(settings_cls),)


sys.argv = ["example.py", "--value", "3"]

print(Settings().model_dump())

which, for me, will output the following:

pydantic_core._pydantic_core.ValidationError: 1 validation error for Settings
value
  Field required [type=missing, input_value={}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.11/v/missing

whereas I would expect {'value': 3}.

I understand that in this particular case, I can easily fix this by using CliSettingsSource(settings_cls, cli_parse_args=True) instead of using a model_config.
However, this requirement is not consistent with other CLI-related config variables (e.g. cli_prog_name or cli_kebab_case), which will be read from settings_cls.model_config if not provided in the CliSettingsSource constructor.

My suspicion is that this is due to the check here, where both None and False are used to represent "do not parse command line arguments".
This can very well be the intended behaviour, and there's probably some use case I'm not being properly aware of. In that case, feel free to say so, and I'll happily close this issue. Otherwise, I'm also more than happy to contribute and submit a PR if you want.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions