CLI format_help method support#759
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds support for format_help and print_help methods to the CliApp class, allowing users to programmatically display help messages for CLI applications without triggering argument parsing errors. This addresses issue #736, which requested a way to display help when no subcommand is specified, similar to argparse's print_help() functionality.
Changes:
- Added
CliApp.format_help()andCliApp.print_help()static methods to retrieve and display help messages for Pydantic models - Modified error handling in
run_subcommand()to automatically append help text when a required subcommand is missing - Refactored
BaseSettings.__init__()to split initialization into_settings_init_sources()and_settings_build_values()class methods to enable reuse of parsed CLI settings sources
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
pydantic_settings/main.py |
Added format_help() and print_help() methods, introduced _subcommand_stack tracking, refactored settings initialization into two-phase process, added _build_sources parameter |
pydantic_settings/sources/providers/cli.py |
Added parser attribute to _CliArg, added format_help_method parameter to CLI source initialization, updated parser map type hints |
pydantic_settings/sources/base.py |
Added _suppress_errors parameter to get_subcommand() to enable error capture without raising |
tests/test_source_cli.py |
Added comprehensive tests for format_help() functionality and error message integration |
tests/test_settings.py |
Added @classmethod decorator to settings_customise_sources for consistency |
docs/index.md |
Added documentation section for the new print_help and format_help methods, updated parser customization docs |
Comments suppressed due to low confidence (1)
pydantic_settings/sources/base.py:61
- The _suppress_errors parameter is an implementation detail that should be marked as private (with leading underscore) in the docstring or excluded from public documentation. However, it's missing from the docstring entirely, which could confuse users who inspect the function signature.
"""
Get the subcommand from a model.
Args:
model: The model to get the subcommand from.
is_required: Determines whether a model must have subcommand set and raises error if not
found. Defaults to `True`.
cli_exit_on_error: Determines whether this function exits with error if no subcommand is found.
Defaults to model_config `cli_exit_on_error` value if set. Otherwise, defaults to `True`.
Returns:
The subcommand model if found, otherwise `None`.
Raises:
SystemExit: When no subcommand is found and is_required=`True` and cli_exit_on_error=`True`
(the default).
SettingsError: When no subcommand is found and is_required=`True` and
cli_exit_on_error=`False`.
"""
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Thanks @kschwab for the PR. Copilot left some comments. Please address them if you think they make sense. |
|
Thanks @kschwab |
run_subcommand (added in pydantic#759) built the _parser_map lookup key using the kebab-cased subcommand_alias (e.g. "foo-bar"), but parser construction keys the map using arg.dest which preserves the original field name (e.g. "foo_bar"). At the second nesting level this mismatch causes a KeyError. Use subcommand_arg.dest to build the next subcommand_dest, matching how the map was keyed during construction. This also removes the now unused subcommand_alias local variable. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fixes #736