@@ -1026,6 +1026,7 @@ class CliSettingsSource(EnvSettingsSource, Generic[T]):
10261026 cli_exit_on_error: Determines whether or not the internal parser exits with error info when an error occurs.
10271027 Defaults to `True`.
10281028 cli_prefix: Prefix for command line arguments added under the root parser. Defaults to "".
1029+ cli_flag_prefix_char: The flag prefix character to use for CLI optional arguments. Defaults to '-'.
10291030 cli_implicit_flags: Whether `bool` fields should be implicitly converted into CLI boolean flags.
10301031 (e.g. --flag, --no-flag). Defaults to `False`.
10311032 cli_ignore_unknown_args: Whether to ignore unknown CLI args and parse only known ones. Defaults to `False`.
@@ -1056,6 +1057,7 @@ def __init__(
10561057 cli_use_class_docs_for_groups : bool | None = None ,
10571058 cli_exit_on_error : bool | None = None ,
10581059 cli_prefix : str | None = None ,
1060+ cli_flag_prefix_char : str | None = None ,
10591061 cli_implicit_flags : bool | None = None ,
10601062 cli_ignore_unknown_args : bool | None = None ,
10611063 case_sensitive : bool | None = True ,
@@ -1097,6 +1099,12 @@ def __init__(
10971099 else settings_cls .model_config .get ('cli_exit_on_error' , True )
10981100 )
10991101 self .cli_prefix = cli_prefix if cli_prefix is not None else settings_cls .model_config .get ('cli_prefix' , '' )
1102+ self .cli_flag_prefix_char = (
1103+ cli_flag_prefix_char
1104+ if cli_flag_prefix_char is not None
1105+ else settings_cls .model_config .get ('cli_flag_prefix_char' , '-' )
1106+ )
1107+ self ._cli_flag_prefix = self .cli_flag_prefix_char * 2
11001108 if self .cli_prefix :
11011109 if cli_prefix .startswith ('.' ) or cli_prefix .endswith ('.' ) or not cli_prefix .replace ('.' , '' ).isidentifier (): # type: ignore
11021110 raise SettingsError (f'CLI settings source prefix is invalid: { cli_prefix } ' )
@@ -1131,6 +1139,7 @@ def __init__(
11311139 prog = self .cli_prog_name ,
11321140 description = None if settings_cls .__doc__ is None else dedent (settings_cls .__doc__ ),
11331141 formatter_class = formatter_class ,
1142+ prefix_chars = self .cli_flag_prefix_char ,
11341143 )
11351144 if root_parser is None
11361145 else root_parser
@@ -1503,7 +1512,8 @@ def parse_args_insensitive_method(
15031512 ) -> Any :
15041513 insensitive_args = []
15051514 for arg in shlex .split (shlex .join (args )) if args else []:
1506- matched = re .match (r'^(--[^\s=]+)(.*)' , arg )
1515+ flag_prefix = rf'\{ self .cli_flag_prefix_char } '
1516+ matched = re .match (rf'^({ flag_prefix } [^\s=]+)(.*)' , arg )
15071517 if matched :
15081518 arg = matched .group (1 ).lower () + matched .group (2 )
15091519 insensitive_args .append (arg )
@@ -1621,7 +1631,7 @@ def _add_parser_args(
16211631 model_default = PydanticUndefined ,
16221632 )
16231633 else :
1624- arg_flag : str = '--'
1634+ flag_prefix : str = self . _cli_flag_prefix
16251635 is_append_action = _annotation_contains_types (
16261636 field_info .annotation , (list , set , dict , Sequence , Mapping ), is_strip_annotated = True
16271637 )
@@ -1655,7 +1665,7 @@ def _add_parser_args(
16551665 arg_names = [kwargs ['dest' ]]
16561666 del kwargs ['dest' ]
16571667 del kwargs ['required' ]
1658- arg_flag = ''
1668+ flag_prefix = ''
16591669
16601670 self ._convert_bool_flag (kwargs , field_info , model_default )
16611671
@@ -1666,7 +1676,7 @@ def _add_parser_args(
16661676 added_args ,
16671677 arg_prefix ,
16681678 subcommand_prefix ,
1669- arg_flag ,
1679+ flag_prefix ,
16701680 arg_names ,
16711681 kwargs ,
16721682 field_name ,
@@ -1679,10 +1689,12 @@ def _add_parser_args(
16791689 if isinstance (group , dict ):
16801690 group = self ._add_argument_group (parser , ** group )
16811691 added_args += list (arg_names )
1682- self ._add_argument (group , * (f'{ arg_flag [:len (name )]} { name } ' for name in arg_names ), ** kwargs )
1692+ self ._add_argument (group , * (f'{ flag_prefix [:len (name )]} { name } ' for name in arg_names ), ** kwargs )
16831693 else :
16841694 added_args += list (arg_names )
1685- self ._add_argument (parser , * (f'{ arg_flag [:len (name )]} { name } ' for name in arg_names ), ** kwargs )
1695+ self ._add_argument (
1696+ parser , * (f'{ flag_prefix [:len (name )]} { name } ' for name in arg_names ), ** kwargs
1697+ )
16861698
16871699 self ._add_parser_alias_paths (parser , alias_path_args , added_args , arg_prefix , subcommand_prefix , group )
16881700 return parser
@@ -1723,7 +1735,7 @@ def _add_parser_submodels(
17231735 added_args : list [str ],
17241736 arg_prefix : str ,
17251737 subcommand_prefix : str ,
1726- arg_flag : str ,
1738+ flag_prefix : str ,
17271739 arg_names : list [str ],
17281740 kwargs : dict [str , Any ],
17291741 field_name : str ,
@@ -1758,7 +1770,7 @@ def _add_parser_submodels(
17581770 added_args .append (arg_names [0 ])
17591771 kwargs ['help' ] = f'set { arg_names [0 ]} from JSON string'
17601772 model_group = self ._add_argument_group (parser , ** model_group_kwargs )
1761- self ._add_argument (model_group , * (f'{ arg_flag } { name } ' for name in arg_names ), ** kwargs )
1773+ self ._add_argument (model_group , * (f'{ flag_prefix } { name } ' for name in arg_names ), ** kwargs )
17621774 for model in sub_models :
17631775 self ._add_parser_args (
17641776 parser = parser ,
@@ -1804,7 +1816,7 @@ def _add_parser_alias_paths(
18041816 kwargs ['metavar' ] = 'list'
18051817 if arg_name not in added_args :
18061818 added_args .append (arg_name )
1807- self ._add_argument (context , f'-- { arg_name } ' , ** kwargs )
1819+ self ._add_argument (context , f'{ self . _cli_flag_prefix } { arg_name } ' , ** kwargs )
18081820
18091821 def _get_modified_args (self , obj : Any ) -> tuple [str , ...]:
18101822 if not self .cli_hide_none_type :
0 commit comments