cmd2.argparse_custom
cmd2.argparse_custom
Module adds capabilities to argparse by patching a few of its functions.
It also defines a parser class called Cmd2ArgumentParser which improves error and help output over normal argparse. All cmd2 code uses this parser and it is recommended that developers of cmd2-based apps either use it or write their own parser that inherits from it. This will give a consistent look-and-feel between the help/error output of built-in cmd2 commands and the app-specific commands. If you wish to override the parser used by cmd2's built-in commands, see custom_parser.py example.
Since the new capabilities are added by patching at the argparse API level, they are available whether or not Cmd2ArgumentParser is used. However, the help and error output of Cmd2ArgumentParser is customized to notate nargs ranges whereas any other parser class won't be as explicit in their output.
Added capabilities
Extends argparse nargs functionality by allowing tuples which specify a range (min, max). To specify a max value with no upper bound, use a 1-item tuple (min,)
Example::
# -f argument expects at least 3 values
parser.add_argument('-f', nargs=(3,))
# -f argument expects 3 to 5 values
parser.add_argument('-f', nargs=(3, 5))
Tab Completion
cmd2 uses its ArgparseCompleter class to enable argparse-based tab completion on all commands that use the @with_argparse wrappers. Out of the box you get tab completion of commands, subcommands, and flag names, as well as instructive hints about the current argument that print when tab is pressed. In addition, you can add tab completion for each argument's values using parameters passed to add_argument().
Below are the 3 add_argument() parameters for enabling tab completion of an argument's value. Only one can be used at a time.
choices - pass a list of values to the choices parameter.
Example::
my_list = ['An Option', 'SomeOtherOption']
parser.add_argument('-o', '--options', choices=my_list)
choices_provider - pass a function that returns choices. This is good in
cases where the choice list is dynamically generated when the user hits tab.
Example::
def my_choices_provider(self):
...
return my_generated_list
parser.add_argument("arg", choices_provider=my_choices_provider)
completer - pass a tab completion function that does custom completion.
cmd2 provides a few completer methods for convenience (e.g., path_complete, delimiter_complete)
Example::
# This adds file-path completion to an argument
parser.add_argument('-o', '--options', completer=cmd2.Cmd.path_complete)
You can use functools.partial() to prepopulate values of the underlying
choices and completer functions/methods.
Example::
# This says to call path_complete with a preset value for its path_filter argument
dir_completer = functools.partial(path_complete,
path_filter=lambda path: os.path.isdir(path))
parser.add_argument('-o', '--options', completer=dir_completer)
For choices_provider and completer, do not set them to a bound method. This
is because ArgparseCompleter passes the self argument explicitly to these
functions. When ArgparseCompleter calls one, it will detect whether it is bound
to a Cmd subclass or CommandSet. If bound to a cmd2.Cmd subclass, it will
pass the app instance as the self argument. If bound to a cmd2.CommandSet
subclass, it will pass the CommandSet instance as the self argument.
Therefore instead of passing something like self.path_complete, pass
cmd2.Cmd.path_complete.
choices_provider and completer functions can also be implemented as
standalone functions (i.e. not a member of a class). In this case,
ArgparseCompleter will pass its cmd2.Cmd app instance as the first
positional argument.
Of the 3 tab completion parameters, choices is the only one where argparse
validates user input against items in the choices list. This is because the
other 2 parameters are meant to tab complete data sets that are viewed as
dynamic. Therefore it is up to the developer to validate if the user has typed
an acceptable value for these arguments.
There are times when what's being tab completed is determined by a previous argument on the command line. In these cases, ArgparseCompleter can pass a dictionary that maps the command line tokens up through the one being completed to their argparse argument name. To receive this dictionary, your choices/completer function should have an argument called arg_tokens.
Example::
def my_choices_provider(self, arg_tokens)
def my_completer(self, text, line, begidx, endidx, arg_tokens)
All values of the arg_tokens dictionary are lists, even if a particular argument expects only 1 token. Since ArgparseCompleter is for tab completion, it does not convert the tokens to their actual argument types or validate their values. All tokens are stored in the dictionary as the raw strings provided on the command line. It is up to the developer to determine if the user entered the correct argument type (e.g. int) and validate their values.
CompletionItem Class - This class was added to help in cases where uninformative data is being tab completed. For instance, tab completing ID numbers isn't very helpful to a user without context. Returning a list of CompletionItems instead of a regular string for completion results will signal the ArgparseCompleter to output the completion results in a table of completion tokens with descriptive data instead of just a table of tokens::
Instead of this:
1 2 3
The user sees this:
ITEM_ID Description
────────────────────────────
1 My item
2 Another item
3 Yet another item
The left-most column is the actual value being tab completed and its header is
that value's name. The right column header is defined using the
descriptive_headers parameter of add_argument(), which is a list of header
names that defaults to ["Description"]. The right column values come from the
CompletionItem.descriptive_data member, which is a list with the same number
of items as columns defined in descriptive_headers.
To use CompletionItems, just return them from your choices_provider or completer functions. They can also be used as argparse choices. When a CompletionItem is created, it stores the original value (e.g. ID number) and makes it accessible through a property called orig_value. cmd2 has patched argparse so that when evaluating choices, input is compared to CompletionItem.orig_value instead of the CompletionItem instance.
Example::
Add an argument and define its descriptive_headers.
parser.add_argument(
add_argument(
"item_id",
type=int,
choices_provider=get_items,
descriptive_headers=["Item Name", "Checked Out", "Due Date"],
)
Implement the choices_provider to return CompletionItems.
def get_items(self) -> list[CompletionItems]:
"""choices_provider which returns CompletionItems"""
# CompletionItem's second argument is descriptive_data.
# Its item count should match that of descriptive_headers.
return [
CompletionItem(1, ["My item", True, "02/02/2022"]),
CompletionItem(2, ["Another item", False, ""]),
CompletionItem(3, ["Yet another item", False, ""]),
]
This is what the user will see during tab completion.
ITEM_ID Item Name Checked Out Due Date
───────────────────────────────────────────────────────
1 My item True 02/02/2022
2 Another item False
3 Yet another item False
descriptive_headers can be strings or Rich.table.Columns for more
control over things like alignment.
-
If a header is a string, it will render as a left-aligned column with its overflow behavior set to "fold". This means a long string will wrap within its cell, creating as many new lines as required to fit.
-
If a header is a
Column, it defaults to "ellipsis" overflow behavior. This means a long string which exceeds the width of its column will be truncated with an ellipsis at the end. You can override this and other settings when you create theColumn.
descriptive_data items can include Rich objects, including styled Text and Tables.
To avoid printing a excessive information to the screen at once when a user
presses tab, there is a maximum threshold for the number of CompletionItems
that will be shown. Its value is defined in cmd2.Cmd.max_completion_items.
It defaults to 50, but can be changed. If the number of completion suggestions
exceeds this number, they will be displayed in the typical columnized format
and will not include the descriptive_data of the CompletionItems.
Patched argparse functions
argparse._ActionsContainer.add_argument - adds arguments related to tab
completion and enables nargs range parsing. See _add_argument_wrapper for
more details on these arguments.
argparse.ArgumentParser._check_value - adds support for using
CompletionItems as argparse choices. When evaluating choices, input is
compared to CompletionItem.orig_value instead of the CompletionItem
instance.
See _ArgumentParser_check_value for more details.
argparse.ArgumentParser._get_nargs_pattern - adds support for nargs ranges.
See _get_nargs_pattern_wrapper for more details.
argparse.ArgumentParser._match_argument - adds support for nargs ranges.
See _match_argument_wrapper for more details.
argparse._SubParsersAction.remove_parser - new function which removes a
sub-parser from a sub-parsers group. See _SubParsersAction_remove_parser for
more details.
Added accessor methods
cmd2 has patched argparse.Action to include the following accessor methods
for cases in which you need to manually access the cmd2-specific attributes.
argparse.Action.get_choices_callable()- Seeaction_get_choices_callablefor more details.argparse.Action.set_choices_provider()- See_action_set_choices_providerfor more details.argparse.Action.set_completer()- See_action_set_completerfor more details.argparse.Action.get_descriptive_headers()- See_action_get_descriptive_headersfor more details.argparse.Action.set_descriptive_headers()- See_action_set_descriptive_headersfor more details.argparse.Action.get_nargs_range()- See_action_get_nargs_rangefor more details.argparse.Action.set_nargs_range()- See_action_set_nargs_rangefor more details.argparse.Action.get_suppress_tab_hint()- See_action_get_suppress_tab_hintfor more details.argparse.Action.set_suppress_tab_hint()- See_action_set_suppress_tab_hintfor more details.
cmd2 has patched argparse.ArgumentParser to include the following accessor methods
argparse.ArgumentParser.get_ap_completer_type()- See_ArgumentParser_get_ap_completer_typefor more details.argparse.Action.set_ap_completer_type()- See_ArgumentParser_set_ap_completer_typefor more details.
Subcommand removal
cmd2 has patched argparse._SubParsersAction to include a remove_parser()
method which can be used to remove a subcommand.
argparse._SubParsersAction.remove_parser - new function which removes a
sub-parser from a sub-parsers group. See _SubParsersAction_remove_parser` for more details.
ChoicesProviderFunc
module-attribute
ChoicesProviderFunc = ChoicesProviderFuncBase | ChoicesProviderFuncWithTokens
orig_actions_container_add_argument
module-attribute
orig_actions_container_add_argument = add_argument
orig_argument_parser_get_nargs_pattern
module-attribute
orig_argument_parser_match_argument
module-attribute
CompletionItem
Bases: str
Completion item with descriptive text attached.
See header of this file for more information
CompletionItem Initializer.
| PARAMETER | DESCRIPTION |
|---|---|
value
|
the value being tab completed
TYPE:
|
descriptive_data
|
a list of descriptive data to display in the columns that follow the completion value. The number of items in this list must equal the number of descriptive headers defined for the argument.
TYPE:
|
args
|
args for str init
TYPE:
|
Source code in cmd2/argparse_custom.py
descriptive_data
instance-attribute
descriptive_data = prepare_objects_for_rendering(*renderable_data)
ChoicesProviderFuncBase
Bases: Protocol
Function that returns a list of choices in support of tab completion.
ChoicesProviderFuncWithTokens
Bases: Protocol
Function that returns a list of choices in support of tab completion and accepts a dictionary of prior arguments.
CompleterFuncBase
Bases: Protocol
Function to support tab completion with the provided state of the user prompt.
CompleterFuncWithTokens
Bases: Protocol
Function to support tab completion with the provided state of the user prompt, accepts a dictionary of prior args.
ChoicesCallable
Enables using a callable as the choices provider for an argparse argument.
While argparse has the built-in choices attribute, it is limited to an iterable.
Initialize the ChoiceCallable instance.
| PARAMETER | DESCRIPTION |
|---|---|
is_completer
|
True if to_call is a tab completion routine which expects the args: text, line, begidx, endidx
TYPE:
|
to_call
|
the callable object that will be called to provide choices for the argument.
TYPE:
|
Source code in cmd2/argparse_custom.py
completer
property
Retreive the internal Completer function, first type checking to ensure it is the right type.
Cmd2HelpFormatter
Cmd2HelpFormatter(prog, indent_increment=2, max_help_position=24, width=None, *, console=None, **kwargs)
Bases: RichHelpFormatter
Custom help formatter to configure ordering of help text.
Initialize Cmd2HelpFormatter.
Source code in cmd2/argparse_custom.py
RawDescriptionCmd2HelpFormatter
RawDescriptionCmd2HelpFormatter(prog, indent_increment=2, max_help_position=24, width=None, *, console=None, **kwargs)
Bases: RawDescriptionRichHelpFormatter, Cmd2HelpFormatter
Cmd2 help message formatter which retains any formatting in descriptions and epilogs.
Initialize Cmd2HelpFormatter.
Source code in cmd2/argparse_custom.py
RawTextCmd2HelpFormatter
RawTextCmd2HelpFormatter(prog, indent_increment=2, max_help_position=24, width=None, *, console=None, **kwargs)
Bases: RawTextRichHelpFormatter, Cmd2HelpFormatter
Cmd2 help message formatter which retains formatting of all help text.
Initialize Cmd2HelpFormatter.
Source code in cmd2/argparse_custom.py
ArgumentDefaultsCmd2HelpFormatter
ArgumentDefaultsCmd2HelpFormatter(prog, indent_increment=2, max_help_position=24, width=None, *, console=None, **kwargs)
Bases: ArgumentDefaultsRichHelpFormatter, Cmd2HelpFormatter
Cmd2 help message formatter which adds default values to argument help.
Initialize Cmd2HelpFormatter.
Source code in cmd2/argparse_custom.py
MetavarTypeCmd2HelpFormatter
MetavarTypeCmd2HelpFormatter(prog, indent_increment=2, max_help_position=24, width=None, *, console=None, **kwargs)
Bases: MetavarTypeRichHelpFormatter, Cmd2HelpFormatter
Cmd2 help message formatter which uses the argument 'type' as the default metavar value (instead of the argument 'dest').
Initialize Cmd2HelpFormatter.
Source code in cmd2/argparse_custom.py
TextGroup
A block of text which is formatted like an argparse argument group, including a title.
Title: Here is the first row of text. Here is yet another row of text.
TextGroup initializer.
| PARAMETER | DESCRIPTION |
|---|---|
title
|
the group's title
TYPE:
|
text
|
the group's text (string or object that may be rendered by Rich)
TYPE:
|
formatter_creator
|
callable which returns a Cmd2HelpFormatter instance
TYPE:
|
Source code in cmd2/argparse_custom.py
Cmd2ArgumentParser
Cmd2ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=(), formatter_class=Cmd2HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True, allow_abbrev=True, exit_on_error=True, suggest_on_error=False, color=False, *, ap_completer_type=None)
Bases: ArgumentParser
Custom ArgumentParser class that improves error and help output.
Initialize the Cmd2ArgumentParser instance, a custom ArgumentParser added by cmd2.
| PARAMETER | DESCRIPTION |
|---|---|
ap_completer_type
|
optional parameter which specifies a subclass of ArgparseCompleter for custom tab completion behavior on this parser. If this is None or not present, then cmd2 will use argparse_completer.DEFAULT_AP_COMPLETER when tab completing this parser's arguments
TYPE:
|
Source code in cmd2/argparse_custom.py
add_subparsers
Add a subcommand parser.
Set a default title if one was not given.
| PARAMETER | DESCRIPTION |
|---|---|
kwargs
|
additional keyword arguments
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
_SubParsersAction
|
argparse Subparser Action |
Source code in cmd2/argparse_custom.py
error
Override that applies custom formatting to the error message.
Source code in cmd2/argparse_custom.py
format_help
create_text_group
Create a TextGroup using this parser's formatter creator.
register
set_defaults
Source code in python3.14/argparse.py
get_default
add_argument
add_argument(dest, ..., name=value, ...) add_argument(option_string, option_string, ..., name=value, ...)
Source code in python3.14/argparse.py
add_argument_group
add_mutually_exclusive_group
parse_args
Source code in python3.14/argparse.py
parse_known_args
convert_arg_line_to_args
parse_intermixed_args
Source code in python3.14/argparse.py
parse_known_intermixed_args
Source code in python3.14/argparse.py
format_usage
print_usage
print_help
Cmd2AttributeWrapper
Wraps a cmd2-specific attribute added to an argparse Namespace.
This makes it easy to know which attributes in a Namespace are arguments from a parser and which were added by cmd2.
Initialize Cmd2AttributeWrapper instances.
Source code in cmd2/argparse_custom.py
get
generate_range_error
Generate an error message when the the number of arguments provided is not within the expected range.
Source code in cmd2/argparse_custom.py
set_parser_prog
Recursively set prog attribute of a parser and all of its subparsers.
Does so that the root command is a command name and not sys.argv[0].
| PARAMETER | DESCRIPTION |
|---|---|
parser
|
the parser being edited
TYPE:
|
prog
|
new value for the parser's prog attribute
TYPE:
|
Source code in cmd2/argparse_custom.py
register_argparse_argument_parameter
Register a custom argparse argument parameter.
The registered name will then be a recognized keyword parameter to the parser's add_argument() function.
An accessor functions will be added to the parameter's Action object in the form of: get_{param_name}()
and set_{param_name}(value).
| PARAMETER | DESCRIPTION |
|---|---|
param_name
|
Name of the parameter to add.
TYPE:
|
param_type
|
Type of the parameter to add.
TYPE:
|
Source code in cmd2/argparse_custom.py
set_default_argument_parser_type
Set the default ArgumentParser class for cmd2's built-in commands.
Since built-in commands rely on customizations made in Cmd2ArgumentParser, your custom parser class should inherit from Cmd2ArgumentParser.
This should be called prior to instantiating your CLI object.
See examples/custom_parser.py.