summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Leonhardt <todd.leonhardt@gmail.com>2021-02-19 21:40:15 -0500
committerTodd Leonhardt <todd.leonhardt@gmail.com>2021-02-19 21:40:15 -0500
commit486b8c726a7d657ef320e68598077c31fa664790 (patch)
tree46b53d0f530d6ae273c4379272684ee80026658a
parent3e180a810e9c4b9d251c135667d1d150b0bbd0dd (diff)
downloadcmd2-git-486b8c726a7d657ef320e68598077c31fa664790.tar.gz
Fixed black, isort, flake8, and doc8 issues
-rw-r--r--cmd2/argparse_completer.py43
-rw-r--r--cmd2/argparse_custom.py30
-rw-r--r--cmd2/cmd2.py230
-rw-r--r--cmd2/decorators.py11
-rw-r--r--cmd2/exceptions.py2
-rw-r--r--cmd2/utils.py19
-rwxr-xr-xexamples/arg_decorators.py3
-rw-r--r--examples/argparse_completion.py40
-rw-r--r--examples/modular_commands_main.py30
-rw-r--r--examples/read_input.py34
-rw-r--r--setup.cfg2
-rw-r--r--tests/test_argparse_completer.py270
-rw-r--r--tests/test_argparse_custom.py23
-rwxr-xr-xtests/test_cmd2.py17
-rwxr-xr-xtests/test_completion.py6
-rwxr-xr-xtests/test_history.py5
16 files changed, 445 insertions, 320 deletions
diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py
index 99378733..f19e9e2c 100644
--- a/cmd2/argparse_completer.py
+++ b/cmd2/argparse_completer.py
@@ -208,8 +208,9 @@ class ArgparseCompleter:
if isinstance(action, argparse._SubParsersAction):
self._subcommand_action = action
- def complete(self, text: str, line: str, begidx: int, endidx: int, tokens: List[str], *,
- cmd_set: Optional[CommandSet] = None) -> List[str]:
+ def complete(
+ self, text: str, line: str, begidx: int, endidx: int, tokens: List[str], *, cmd_set: Optional[CommandSet] = None
+ ) -> List[str]:
"""
Complete text using argparse metadata
@@ -391,10 +392,12 @@ class ArgparseCompleter:
if action.dest != argparse.SUPPRESS:
parent_tokens[action.dest] = [token]
- completer = ArgparseCompleter(self._subcommand_action.choices[token], self._cmd2_app,
- parent_tokens=parent_tokens)
- return completer.complete(text, line, begidx, endidx, tokens[token_index + 1:],
- cmd_set=cmd_set)
+ completer = ArgparseCompleter(
+ self._subcommand_action.choices[token], self._cmd2_app, parent_tokens=parent_tokens
+ )
+ return completer.complete(
+ text, line, begidx, endidx, tokens[token_index + 1 :], cmd_set=cmd_set
+ )
else:
# Invalid subcommand entered, so no way to complete remaining tokens
return []
@@ -438,8 +441,9 @@ class ArgparseCompleter:
# Check if we are completing a flag's argument
if flag_arg_state is not None:
- completion_results = self._complete_arg(text, line, begidx, endidx, flag_arg_state, consumed_arg_values,
- cmd_set=cmd_set)
+ completion_results = self._complete_arg(
+ text, line, begidx, endidx, flag_arg_state, consumed_arg_values, cmd_set=cmd_set
+ )
# If we have results, then return them
if completion_results:
@@ -464,8 +468,9 @@ class ArgparseCompleter:
action = remaining_positionals.popleft()
pos_arg_state = _ArgumentState(action)
- completion_results = self._complete_arg(text, line, begidx, endidx, pos_arg_state, consumed_arg_values,
- cmd_set=cmd_set)
+ completion_results = self._complete_arg(
+ text, line, begidx, endidx, pos_arg_state, consumed_arg_values, cmd_set=cmd_set
+ )
# If we have results, then return them
if completion_results:
@@ -587,7 +592,7 @@ class ArgparseCompleter:
for token_index, token in enumerate(tokens):
if token in self._subcommand_action.choices:
completer = ArgparseCompleter(self._subcommand_action.choices[token], self._cmd2_app)
- return completer.complete_subcommand_help(text, line, begidx, endidx, tokens[token_index + 1:])
+ return completer.complete_subcommand_help(text, line, begidx, endidx, tokens[token_index + 1 :])
elif token_index == len(tokens) - 1:
# Since this is the last token, we will attempt to complete it
return self._cmd2_app.basic_complete(text, line, begidx, endidx, self._subcommand_action.choices)
@@ -607,14 +612,22 @@ class ArgparseCompleter:
for token_index, token in enumerate(tokens):
if token in self._subcommand_action.choices:
completer = ArgparseCompleter(self._subcommand_action.choices[token], self._cmd2_app)
- return completer.format_help(tokens[token_index + 1:])
+ return completer.format_help(tokens[token_index + 1 :])
else:
break
return self._parser.format_help()
- def _complete_arg(self, text: str, line: str, begidx: int, endidx: int,
- arg_state: _ArgumentState, consumed_arg_values: Dict[str, List[str]], *,
- cmd_set: Optional[CommandSet] = None) -> List[str]:
+ def _complete_arg(
+ self,
+ text: str,
+ line: str,
+ begidx: int,
+ endidx: int,
+ arg_state: _ArgumentState,
+ consumed_arg_values: Dict[str, List[str]],
+ *,
+ cmd_set: Optional[CommandSet] = None
+ ) -> List[str]:
"""
Tab completion routine for an argparse argument
:return: list of completions
diff --git a/cmd2/argparse_custom.py b/cmd2/argparse_custom.py
index 26921ade..d3f819b2 100644
--- a/cmd2/argparse_custom.py
+++ b/cmd2/argparse_custom.py
@@ -285,6 +285,7 @@ class 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.
"""
+
def __init__(self, is_completer: bool, to_call: Callable):
"""
Initializer
@@ -305,12 +306,13 @@ def _set_choices_callable(action: argparse.Action, choices_callable: ChoicesCall
"""
# Verify consistent use of parameters
if action.choices is not None:
- err_msg = ("None of the following parameters can be used alongside a choices parameter:\n"
- "choices_provider, completer")
+ err_msg = "None of the following parameters can be used alongside a choices parameter:\n" "choices_provider, completer"
raise (TypeError(err_msg))
elif action.nargs == 0:
- err_msg = ("None of the following parameters can be used on an action that takes no arguments:\n"
- "choices_provider, completer")
+ err_msg = (
+ "None of the following parameters can be used on an action that takes no arguments:\n"
+ "choices_provider, completer"
+ )
raise (TypeError(err_msg))
setattr(action, ATTR_CHOICES_CALLABLE, choices_callable)
@@ -335,13 +337,16 @@ def set_completer(action: argparse.Action, completer: Callable) -> None:
orig_actions_container_add_argument = argparse._ActionsContainer.add_argument
-def _add_argument_wrapper(self, *args,
- nargs: Union[int, str, Tuple[int], Tuple[int, int], None] = None,
- choices_provider: Optional[Callable] = None,
- completer: Optional[Callable] = None,
- suppress_tab_hint: bool = False,
- descriptive_header: Optional[str] = None,
- **kwargs) -> argparse.Action:
+def _add_argument_wrapper(
+ self,
+ *args,
+ nargs: Union[int, str, Tuple[int], Tuple[int, int], None] = None,
+ choices_provider: Optional[Callable] = None,
+ completer: Optional[Callable] = None,
+ suppress_tab_hint: bool = False,
+ descriptive_header: Optional[str] = None,
+ **kwargs
+) -> argparse.Action:
"""
Wrapper around _ActionsContainer.add_argument() which supports more settings used by cmd2
@@ -379,8 +384,7 @@ def _add_argument_wrapper(self, *args,
num_params_set = len(choices_callables) - choices_callables.count(None)
if num_params_set > 1:
- err_msg = ("Only one of the following parameters may be used at a time:\n"
- "choices_provider, completer")
+ err_msg = "Only one of the following parameters may be used at a time:\n" "choices_provider, completer"
raise (ValueError(err_msg))
# Pre-process special ranged nargs
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 88fdcd87..fd757891 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -1208,8 +1208,9 @@ class Cmd(cmd.Cmd):
"""
return [cur_match for cur_match in match_against if cur_match.startswith(text)]
- def delimiter_complete(self, text: str, line: str, begidx: int, endidx: int,
- match_against: Iterable, delimiter: str) -> List[str]:
+ def delimiter_complete(
+ self, text: str, line: str, begidx: int, endidx: int, match_against: Iterable, delimiter: str
+ ) -> List[str]:
"""
Performs tab completion against a list but each match is split on a delimiter and only
the portion of the match being tab completed is shown as the completion suggestions.
@@ -1737,8 +1738,9 @@ class Cmd(cmd.Cmd):
# Display matches using actual display function. This also redraws the prompt and line.
orig_pyreadline_display(matches_to_display)
- def _perform_completion(self, text: str, line: str, begidx: int, endidx: int,
- custom_settings: Optional[utils.CustomCompletionSettings] = None) -> None:
+ def _perform_completion(
+ self, text: str, line: str, begidx: int, endidx: int, custom_settings: Optional[utils.CustomCompletionSettings] = None
+ ) -> None:
"""
Helper function for complete() that performs the actual completion
@@ -1748,7 +1750,9 @@ class Cmd(cmd.Cmd):
:param endidx: the ending index of the prefix text
:param custom_settings: optional prepopulated completion settings
"""
- from .argparse_completer import ArgparseCompleter
+ from .argparse_completer import (
+ ArgparseCompleter,
+ )
unclosed_quote = ''
command = None
@@ -1806,9 +1810,9 @@ class Cmd(cmd.Cmd):
completer = ArgparseCompleter(argparser, self)
preserve_quotes = getattr(func, constants.CMD_ATTR_PRESERVE_QUOTES)
- completer_func = functools.partial(completer.complete,
- tokens=raw_tokens[1:] if preserve_quotes else tokens[1:],
- cmd_set=cmd_set)
+ completer_func = functools.partial(
+ completer.complete, tokens=raw_tokens[1:] if preserve_quotes else tokens[1:], cmd_set=cmd_set
+ )
else:
completer_func = self.completedefault
@@ -1823,9 +1827,9 @@ class Cmd(cmd.Cmd):
# Otherwise we are completing the command token or performing custom completion
else:
completer = ArgparseCompleter(custom_settings.parser, self)
- completer_func = functools.partial(completer.complete,
- tokens=raw_tokens if custom_settings.preserve_quotes else tokens,
- cmd_set=None)
+ completer_func = functools.partial(
+ completer.complete, tokens=raw_tokens if custom_settings.preserve_quotes else tokens, cmd_set=None
+ )
# Text we need to remove from completions later
text_to_remove = ''
@@ -1910,8 +1914,9 @@ class Cmd(cmd.Cmd):
if len(self.completion_matches) == 1 and self.allow_closing_quote and unclosed_quote:
self.completion_matches[0] += unclosed_quote
- def complete(self, text: str, state: int,
- custom_settings: Optional[utils.CustomCompletionSettings] = None) -> Optional[str]:
+ def complete(
+ self, text: str, state: int, custom_settings: Optional[utils.CustomCompletionSettings] = None
+ ) -> Optional[str]:
"""Override of cmd2's complete method which returns the next possible completion for 'text'
This completer function is called by readline as complete(text, state), for state in 0, 1, 2, …,
@@ -1968,8 +1973,12 @@ class Cmd(cmd.Cmd):
else:
# No shortcut was found. Complete the command token.
parser = DEFAULT_ARGUMENT_PARSER(add_help=False)
- parser.add_argument('command', metavar="COMMAND", help="command, alias, or macro name",
- choices=self._get_commands_aliases_and_macros_for_completion())
+ parser.add_argument(
+ 'command',
+ metavar="COMMAND",
+ help="command, alias, or macro name",
+ choices=self._get_commands_aliases_and_macros_for_completion(),
+ )
custom_settings = utils.CustomCompletionSettings(parser)
self._perform_completion(text, line, begidx, endidx, custom_settings)
@@ -2674,14 +2683,18 @@ class Cmd(cmd.Cmd):
# Set apply_style to False so default_error's style is not overridden
self.perror(err_msg, apply_style=False)
- def read_input(self, prompt: str, *,
- history: Optional[List[str]] = None,
- completion_mode: utils.CompletionMode = utils.CompletionMode.NONE,
- preserve_quotes: bool = False,
- choices: Iterable = None,
- choices_provider: Optional[Callable] = None,
- completer: Optional[Callable] = None,
- parser: Optional[argparse.ArgumentParser] = None) -> str:
+ def read_input(
+ self,
+ prompt: str,
+ *,
+ history: Optional[List[str]] = None,
+ completion_mode: utils.CompletionMode = utils.CompletionMode.NONE,
+ preserve_quotes: bool = False,
+ choices: Iterable = None,
+ choices_provider: Optional[Callable] = None,
+ completer: Optional[Callable] = None,
+ parser: Optional[argparse.ArgumentParser] = None
+ ) -> str:
"""
Read input from appropriate stdin value. Also supports tab completion and up-arrow history while
input is being entered.
@@ -2736,6 +2749,7 @@ class Cmd(cmd.Cmd):
# noinspection PyUnusedLocal
def complete_none(text: str, state: int): # pragma: no cover
return None
+
complete_func = complete_none
# Complete commands
@@ -2746,8 +2760,13 @@ class Cmd(cmd.Cmd):
else:
if parser is None:
parser = DEFAULT_ARGUMENT_PARSER(add_help=False)
- parser.add_argument('arg', suppress_tab_hint=True, choices=choices,
- choices_provider=choices_provider, completer=completer)
+ parser.add_argument(
+ 'arg',
+ suppress_tab_hint=True,
+ choices=choices,
+ choices_provider=choices_provider,
+ completer=completer,
+ )
custom_settings = utils.CustomCompletionSettings(parser, preserve_quotes=preserve_quotes)
complete_func = functools.partial(self.complete, custom_settings=custom_settings)
@@ -2976,10 +2995,12 @@ class Cmd(cmd.Cmd):
alias_create_parser = DEFAULT_ARGUMENT_PARSER(description=alias_create_description, epilog=alias_create_epilog)
alias_create_parser.add_argument('name', help='name of this alias')
- alias_create_parser.add_argument('command', help='what the alias resolves to',
- choices_provider=_get_commands_aliases_and_macros_for_completion)
- alias_create_parser.add_argument('command_args', nargs=argparse.REMAINDER, help='arguments to pass to command',
- completer=path_complete)
+ alias_create_parser.add_argument(
+ 'command', help='what the alias resolves to', choices_provider=_get_commands_aliases_and_macros_for_completion
+ )
+ alias_create_parser.add_argument(
+ 'command_args', nargs=argparse.REMAINDER, help='arguments to pass to command', completer=path_complete
+ )
@as_subcommand_to('alias', 'create', alias_create_parser, help=alias_create_description.lower())
def _alias_create(self, args: argparse.Namespace) -> None:
@@ -3020,8 +3041,13 @@ class Cmd(cmd.Cmd):
alias_delete_parser = DEFAULT_ARGUMENT_PARSER(description=alias_delete_description)
alias_delete_parser.add_argument('-a', '--all', action='store_true', help="delete all aliases")
- alias_delete_parser.add_argument('names', nargs=argparse.ZERO_OR_MORE, help='alias(es) to delete',
- choices_provider=_get_alias_completion_items, descriptive_header='Value')
+ alias_delete_parser.add_argument(
+ 'names',
+ nargs=argparse.ZERO_OR_MORE,
+ help='alias(es) to delete',
+ choices_provider=_get_alias_completion_items,
+ descriptive_header='Value',
+ )
@as_subcommand_to('alias', 'delete', alias_delete_parser, help=alias_delete_help)
def _alias_delete(self, args: argparse.Namespace) -> None:
@@ -3049,8 +3075,13 @@ class Cmd(cmd.Cmd):
)
alias_list_parser = DEFAULT_ARGUMENT_PARSER(description=alias_list_description)
- alias_list_parser.add_argument('names', nargs=argparse.ZERO_OR_MORE, help='alias(es) to list',
- choices_provider=_get_alias_completion_items, descriptive_header='Value')
+ alias_list_parser.add_argument(
+ 'names',
+ nargs=argparse.ZERO_OR_MORE,
+ help='alias(es) to list',
+ choices_provider=_get_alias_completion_items,
+ descriptive_header='Value',
+ )
@as_subcommand_to('alias', 'list', alias_list_parser, help=alias_delete_help)
def _alias_list(self, args: argparse.Namespace) -> None:
@@ -3146,10 +3177,12 @@ class Cmd(cmd.Cmd):
macro_create_parser = DEFAULT_ARGUMENT_PARSER(description=macro_create_description, epilog=macro_create_epilog)
macro_create_parser.add_argument('name', help='name of this macro')
- macro_create_parser.add_argument('command', help='what the macro resolves to',
- choices_provider=_get_commands_aliases_and_macros_for_completion)
- macro_create_parser.add_argument('command_args', nargs=argparse.REMAINDER,
- help='arguments to pass to command', completer=path_complete)
+ macro_create_parser.add_argument(
+ 'command', help='what the macro resolves to', choices_provider=_get_commands_aliases_and_macros_for_completion
+ )
+ macro_create_parser.add_argument(
+ 'command_args', nargs=argparse.REMAINDER, help='arguments to pass to command', completer=path_complete
+ )
@as_subcommand_to('macro', 'create', macro_create_parser, help=macro_create_help)
def _macro_create(self, args: argparse.Namespace) -> None:
@@ -3234,8 +3267,13 @@ class Cmd(cmd.Cmd):
macro_delete_description = "Delete specified macros or all macros if --all is used"
macro_delete_parser = DEFAULT_ARGUMENT_PARSER(description=macro_delete_description)
macro_delete_parser.add_argument('-a', '--all', action='store_true', help="delete all macros")
- macro_delete_parser.add_argument('names', nargs=argparse.ZERO_OR_MORE, help='macro(s) to delete',
- choices_provider=_get_macro_completion_items, descriptive_header='Value')
+ macro_delete_parser.add_argument(
+ 'names',
+ nargs=argparse.ZERO_OR_MORE,
+ help='macro(s) to delete',
+ choices_provider=_get_macro_completion_items,
+ descriptive_header='Value',
+ )
@as_subcommand_to('macro', 'delete', macro_delete_parser, help=macro_delete_help)
def _macro_delete(self, args: argparse.Namespace) -> None:
@@ -3263,8 +3301,13 @@ class Cmd(cmd.Cmd):
)
macro_list_parser = DEFAULT_ARGUMENT_PARSER(description=macro_list_description)
- macro_list_parser.add_argument('names', nargs=argparse.ZERO_OR_MORE, help='macro(s) to list',
- choices_provider=_get_macro_completion_items, descriptive_header='Value')
+ macro_list_parser.add_argument(
+ 'names',
+ nargs=argparse.ZERO_OR_MORE,
+ help='macro(s) to list',
+ choices_provider=_get_macro_completion_items,
+ descriptive_header='Value',
+ )
@as_subcommand_to('macro', 'list', macro_list_parser, help=macro_list_help)
def _macro_list(self, args: argparse.Namespace) -> None:
@@ -3323,18 +3366,25 @@ class Cmd(cmd.Cmd):
if func is None or argparser is None:
return []
- from .argparse_completer import ArgparseCompleter
+ from .argparse_completer import (
+ ArgparseCompleter,
+ )
+
completer = ArgparseCompleter(argparser, self)
return completer.complete_subcommand_help(text, line, begidx, endidx, arg_tokens['subcommands'])
- help_parser = DEFAULT_ARGUMENT_PARSER(description="List available commands or provide "
- "detailed help for a specific command")
- help_parser.add_argument('-v', '--verbose', action='store_true',
- help="print a list of all commands with descriptions of each")
- help_parser.add_argument('command', nargs=argparse.OPTIONAL, help="command to retrieve help for",
- completer=complete_help_command)
- help_parser.add_argument('subcommands', nargs=argparse.REMAINDER, help="subcommand(s) to retrieve help for",
- completer=complete_help_subcommands)
+ help_parser = DEFAULT_ARGUMENT_PARSER(
+ description="List available commands or provide " "detailed help for a specific command"
+ )
+ help_parser.add_argument(
+ '-v', '--verbose', action='store_true', help="print a list of all commands with descriptions of each"
+ )
+ help_parser.add_argument(
+ 'command', nargs=argparse.OPTIONAL, help="command to retrieve help for", completer=complete_help_command
+ )
+ help_parser.add_argument(
+ 'subcommands', nargs=argparse.REMAINDER, help="subcommand(s) to retrieve help for", completer=complete_help_subcommands
+ )
# Get rid of cmd's complete_help() functions so ArgparseCompleter will complete the help command
if getattr(cmd.Cmd, 'complete_help', None) is not None:
@@ -3591,12 +3641,19 @@ class Cmd(cmd.Cmd):
# Settables with choices list the values of those choices instead of the arg name
# in help text and this shows in tab completion hints. Set metavar to avoid this.
arg_name = 'value'
- settable_parser.add_argument(arg_name, metavar=arg_name, help=settable.description,
- choices=settable.choices,
- choices_provider=settable.choices_provider,
- completer=settable.completer)
+ settable_parser.add_argument(
+ arg_name,
+ metavar=arg_name,
+ help=settable.description,
+ choices=settable.choices,
+ choices_provider=settable.choices_provider,
+ completer=settable.completer,
+ )
+
+ from .argparse_completer import (
+ ArgparseCompleter,
+ )
- from .argparse_completer import ArgparseCompleter
completer = ArgparseCompleter(settable_parser, self)
# Use raw_tokens since quotes have been preserved
@@ -3611,15 +3668,22 @@ class Cmd(cmd.Cmd):
"Call with just param to view that parameter's value."
)
set_parser_parent = DEFAULT_ARGUMENT_PARSER(description=set_description, add_help=False)
- set_parser_parent.add_argument('-v', '--verbose', action='store_true',
- help='include description of parameters when viewing')
- set_parser_parent.add_argument('param', nargs=argparse.OPTIONAL, help='parameter to set or view',
- choices_provider=_get_settable_completion_items, descriptive_header='Description')
+ set_parser_parent.add_argument(
+ '-v', '--verbose', action='store_true', help='include description of parameters when viewing'
+ )
+ set_parser_parent.add_argument(
+ 'param',
+ nargs=argparse.OPTIONAL,
+ help='parameter to set or view',
+ choices_provider=_get_settable_completion_items,
+ descriptive_header='Description',
+ )
# Create the parser for the set command
set_parser = DEFAULT_ARGUMENT_PARSER(parents=[set_parser_parent])
- set_parser.add_argument('value', nargs=argparse.OPTIONAL, help='new value for settable',
- completer=complete_set_value, suppress_tab_hint=True)
+ set_parser.add_argument(
+ 'value', nargs=argparse.OPTIONAL, help='new value for settable', completer=complete_set_value, suppress_tab_hint=True
+ )
# Preserve quotes so users can pass in quoted empty strings and flags (e.g. -h) as the value
@with_argparser(set_parser, preserve_quotes=True)
@@ -3680,8 +3744,9 @@ class Cmd(cmd.Cmd):
shell_parser = DEFAULT_ARGUMENT_PARSER(description="Execute a command as if at the OS prompt")
shell_parser.add_argument('command', help='the command to run', completer=shell_cmd_complete)
- shell_parser.add_argument('command_args', nargs=argparse.REMAINDER, help='arguments to pass to command',
- completer=path_complete)
+ shell_parser.add_argument(
+ 'command_args', nargs=argparse.REMAINDER, help='arguments to pass to command', completer=path_complete
+ )
# Preserve quotes since we are passing these strings to the shell
@with_argparser(shell_parser, preserve_quotes=True)
@@ -3979,8 +4044,9 @@ class Cmd(cmd.Cmd):
run_pyscript_parser = DEFAULT_ARGUMENT_PARSER(description="Run a Python script file inside the console")
run_pyscript_parser.add_argument('script_path', help='path to the script file', completer=path_complete)
- run_pyscript_parser.add_argument('script_arguments', nargs=argparse.REMAINDER,
- help='arguments to pass to script', completer=path_complete)
+ run_pyscript_parser.add_argument(
+ 'script_arguments', nargs=argparse.REMAINDER, help='arguments to pass to script', completer=path_complete
+ )
@with_argparser(run_pyscript_parser)
def do_run_pyscript(self, args: argparse.Namespace) -> Optional[bool]:
@@ -4076,14 +4142,17 @@ class Cmd(cmd.Cmd):
history_parser = DEFAULT_ARGUMENT_PARSER(description=history_description)
history_action_group = history_parser.add_mutually_exclusive_group()
history_action_group.add_argument('-r', '--run', action='store_true', help='run selected history items')
- history_action_group.add_argument('-e', '--edit', action='store_true',
- help='edit and then run selected history items')
- history_action_group.add_argument('-o', '--output_file', metavar='FILE',
- help='output commands to a script file, implies -s',
- completer=path_complete)
- history_action_group.add_argument('-t', '--transcript', metavar='TRANSCRIPT_FILE',
- help='output commands and results to a transcript file,\nimplies -s',
- completer=path_complete)
+ history_action_group.add_argument('-e', '--edit', action='store_true', help='edit and then run selected history items')
+ history_action_group.add_argument(
+ '-o', '--output_file', metavar='FILE', help='output commands to a script file, implies -s', completer=path_complete
+ )
+ history_action_group.add_argument(
+ '-t',
+ '--transcript',
+ metavar='TRANSCRIPT_FILE',
+ help='output commands and results to a transcript file,\nimplies -s',
+ completer=path_complete,
+ )
history_action_group.add_argument('-c', '--clear', action='store_true', help='clear all history')
history_format_group = history_parser.add_argument_group(title='formatting')
@@ -4414,8 +4483,9 @@ class Cmd(cmd.Cmd):
)
edit_parser = DEFAULT_ARGUMENT_PARSER(description=edit_description)
- edit_parser.add_argument('file_path', nargs=argparse.OPTIONAL,
- help="optional path to a file to open in editor", completer=path_complete)
+ edit_parser.add_argument(
+ 'file_path', nargs=argparse.OPTIONAL, help="optional path to a file to open in editor", completer=path_complete
+ )
@with_argparser(edit_parser)
def do_edit(self, args: argparse.Namespace) -> None:
@@ -4458,9 +4528,13 @@ class Cmd(cmd.Cmd):
)
run_script_parser = DEFAULT_ARGUMENT_PARSER(description=run_script_description)
- run_script_parser.add_argument('-t', '--transcript', metavar='TRANSCRIPT_FILE',
- help='record the output of the script as a transcript file',
- completer=path_complete)
+ run_script_parser.add_argument(
+ '-t',
+ '--transcript',
+ metavar='TRANSCRIPT_FILE',
+ help='record the output of the script as a transcript file',
+ completer=path_complete,
+ )
run_script_parser.add_argument('script_path', help="path to the script file", completer=path_complete)
@with_argparser(run_script_parser)
diff --git a/cmd2/decorators.py b/cmd2/decorators.py
index e3a3eaa1..b18cc046 100644
--- a/cmd2/decorators.py
+++ b/cmd2/decorators.py
@@ -196,10 +196,13 @@ def _set_parser_prog(parser: argparse.ArgumentParser, prog: str):
break
-def with_argparser(parser: argparse.ArgumentParser, *,
- ns_provider: Optional[Callable[..., argparse.Namespace]] = None,
- preserve_quotes: bool = False,
- with_unknown_args: bool = False) -> Callable[[argparse.Namespace], Optional[bool]]:
+def with_argparser(
+ parser: argparse.ArgumentParser,
+ *,
+ ns_provider: Optional[Callable[..., argparse.Namespace]] = None,
+ preserve_quotes: bool = False,
+ with_unknown_args: bool = False
+) -> Callable[[argparse.Namespace], Optional[bool]]:
"""A decorator to alter a cmd2 method to populate its ``args`` argument by parsing arguments
with the given instance of argparse.ArgumentParser.
diff --git a/cmd2/exceptions.py b/cmd2/exceptions.py
index b6e18856..c662d8fa 100644
--- a/cmd2/exceptions.py
+++ b/cmd2/exceptions.py
@@ -48,6 +48,7 @@ class CompletionError(Exception):
- A previous command line argument that determines the data set being completed is invalid
- Tab completion hints
"""
+
def __init__(self, *args, apply_style: bool = True, **kwargs):
"""
Initializer for CompletionError
@@ -60,6 +61,7 @@ class CompletionError(Exception):
# noinspection PyArgumentList
super().__init__(*args, **kwargs)
+
############################################################################################################
# The following exceptions are NOT part of the public API and are intended for internal use only.
############################################################################################################
diff --git a/cmd2/utils.py b/cmd2/utils.py
index 8dad5f4c..9920ad64 100644
--- a/cmd2/utils.py
+++ b/cmd2/utils.py
@@ -93,11 +93,18 @@ def str_to_bool(val: str) -> bool:
class Settable:
"""Used to configure a cmd2 instance member to be settable via the set command in the CLI"""
- def __init__(self, name: str, val_type: Callable, description: str, *,
- onchange_cb: Callable[[str, Any, Any], Any] = None,
- choices: Iterable = None,
- choices_provider: Optional[Callable] = None,
- completer: Optional[Callable] = None):
+
+ def __init__(
+ self,
+ name: str,
+ val_type: Callable,
+ description: str,
+ *,
+ onchange_cb: Callable[[str, Any, Any], Any] = None,
+ choices: Iterable = None,
+ choices_provider: Optional[Callable] = None,
+ completer: Optional[Callable] = None
+ ):
"""
Settable Initializer
@@ -1075,6 +1082,7 @@ def get_defining_class(meth) -> Type:
class CompletionMode(Enum):
"""Enum for what type of tab completion to perform in cmd2.Cmd.read_input()"""
+
# Tab completion will be disabled during read_input() call
# Use of custom up-arrow history supported
NONE = 1
@@ -1092,6 +1100,7 @@ class CompletionMode(Enum):
class CustomCompletionSettings:
"""Used by cmd2.Cmd.complete() to tab complete strings other than command arguments"""
+
def __init__(self, parser: argparse.ArgumentParser, *, preserve_quotes: bool = False):
"""
Initializer
diff --git a/examples/arg_decorators.py b/examples/arg_decorators.py
index 49ea9a10..a0d08d43 100755
--- a/examples/arg_decorators.py
+++ b/examples/arg_decorators.py
@@ -16,8 +16,7 @@ class ArgparsingApp(cmd2.Cmd):
fsize_parser = cmd2.Cmd2ArgumentParser(description='Obtain the size of a file')
fsize_parser.add_argument('-c', '--comma', action='store_true', help='add comma for thousands separator')
fsize_parser.add_argument('-u', '--unit', choices=['MB', 'KB'], help='unit to display size in')
- fsize_parser.add_argument('file_path', help='path of file',
- completer=cmd2.Cmd.path_complete)
+ fsize_parser.add_argument('file_path', help='path of file', completer=cmd2.Cmd.path_complete)
@cmd2.with_argparser(fsize_parser)
def do_fsize(self, args: argparse.Namespace) -> None:
diff --git a/examples/argparse_completion.py b/examples/argparse_completion.py
index 5355cd87..fa821b77 100644
--- a/examples/argparse_completion.py
+++ b/examples/argparse_completion.py
@@ -45,12 +45,7 @@ class ArgparseCompletion(Cmd):
# noinspection PyMethodMayBeStatic
def choices_completion_item(self) -> List[CompletionItem]:
"""Return CompletionItem instead of strings. These give more context to what's being tab completed."""
- items = \
- {
- 1: "My item",
- 2: "Another item",
- 3: "Yet another item"
- }
+ items = {1: "My item", 2: "Another item", 3: "Yet another item"}
return [CompletionItem(item_id, description) for item_id, description in items.items()]
# noinspection PyMethodMayBeStatic
@@ -78,29 +73,36 @@ class ArgparseCompletion(Cmd):
# want the entire choices list showing in the usage text for this command.
example_parser.add_argument('--choices', choices=food_item_strs, metavar="CHOICE", help="tab complete using choices")
- example_parser.add_argument('--choices', choices=food_item_strs, metavar="CHOICE",
- help="tab complete using choices")
+ example_parser.add_argument('--choices', choices=food_item_strs, metavar="CHOICE", help="tab complete using choices")
# Tab complete from choices provided by a choices_provider
- example_parser.add_argument('--choices_provider', choices_provider=choices_provider,
- help="tab complete using a choices_provider")
+ example_parser.add_argument(
+ '--choices_provider', choices_provider=choices_provider, help="tab complete using a choices_provider"
+ )
# Tab complete using a completer
- example_parser.add_argument('--completer', completer=Cmd.path_complete,
- help="tab complete using a completer")
+ example_parser.add_argument('--completer', completer=Cmd.path_complete, help="tab complete using a completer")
# Demonstrate raising a CompletionError while tab completing
- example_parser.add_argument('--completion_error', choices_provider=choices_completion_error,
- help="raise a CompletionError while tab completing if debug is False")
+ example_parser.add_argument(
+ '--completion_error',
+ choices_provider=choices_completion_error,
+ help="raise a CompletionError while tab completing if debug is False",
+ )
# Demonstrate returning CompletionItems instead of strings
- example_parser.add_argument('--completion_item', choices_provider=choices_completion_item, metavar="ITEM_ID",
- descriptive_header="Description",
- help="demonstrate use of CompletionItems")
+ example_parser.add_argument(
+ '--completion_item',
+ choices_provider=choices_completion_item,
+ metavar="ITEM_ID",
+ descriptive_header="Description",
+ help="demonstrate use of CompletionItems",
+ )
# Demonstrate use of arg_tokens dictionary
- example_parser.add_argument('--arg_tokens', choices_provider=choices_arg_tokens,
- help="demonstrate use of arg_tokens dictionary")
+ example_parser.add_argument(
+ '--arg_tokens', choices_provider=choices_arg_tokens, help="demonstrate use of arg_tokens dictionary"
+ )
@with_argparser(example_parser)
def do_example(self, _: argparse.Namespace) -> None:
diff --git a/examples/modular_commands_main.py b/examples/modular_commands_main.py
index fc0be7b0..3aeb8b2a 100644
--- a/examples/modular_commands_main.py
+++ b/examples/modular_commands_main.py
@@ -11,20 +11,21 @@ from typing import (
Optional,
)
-from cmd2 import (
- Cmd,
- Cmd2ArgumentParser,
- CommandSet,
- with_argparser,
-)
from modular_commands.commandset_basic import ( # noqa: F401
BasicCompletionCommandSet,
)
from modular_commands.commandset_complex import ( # noqa: F401
CommandSetA,
)
-from modular_commands.commandset_custominit import (
- CustomInitCommandSet, # noqa: F401
+from modular_commands.commandset_custominit import ( # noqa: F401
+ CustomInitCommandSet,
+)
+
+from cmd2 import (
+ Cmd,
+ Cmd2ArgumentParser,
+ CommandSet,
+ with_argparser,
)
@@ -44,16 +45,17 @@ class WithCommandSets(Cmd):
# Tab complete from a list using argparse choices. Set metavar if you don't
# want the entire choices list showing in the usage text for this command.
- example_parser.add_argument('--choices', choices=['some', 'choices', 'here'], metavar="CHOICE",
- help="tab complete using choices")
+ example_parser.add_argument(
+ '--choices', choices=['some', 'choices', 'here'], metavar="CHOICE", help="tab complete using choices"
+ )
# Tab complete from choices provided by a choices provider
- example_parser.add_argument('--choices_provider', choices_provider=choices_provider,
- help="tab complete using a choices_provider")
+ example_parser.add_argument(
+ '--choices_provider', choices_provider=choices_provider, help="tab complete using a choices_provider"
+ )
# Tab complete using a completer
- example_parser.add_argument('--completer', completer=Cmd.path_complete,
- help="tab complete using a completer")
+ example_parser.add_argument('--completer', completer=Cmd.path_complete, help="tab complete using a completer")
@with_argparser(example_parser)
def do_example(self, _: argparse.Namespace) -> None:
diff --git a/examples/read_input.py b/examples/read_input.py
index e772a106..f45fc7c8 100644
--- a/examples/read_input.py
+++ b/examples/read_input.py
@@ -3,7 +3,9 @@
"""
A simple example demonstrating the various ways to call cmd2.Cmd.read_input() for input history and tab completion
"""
-from typing import List
+from typing import (
+ List,
+)
import cmd2
@@ -50,8 +52,12 @@ class ReadInputApp(cmd2.Cmd):
"""Call read_input to use custom history and choices"""
self.poutput("Tab completing with static choices list and using custom history")
try:
- input_str = self.read_input("> ", history=self.custom_history, completion_mode=cmd2.CompletionMode.CUSTOM,
- choices=['choice_1', 'choice_2', 'choice_3'])
+ input_str = self.read_input(
+ "> ",
+ history=self.custom_history,
+ completion_mode=cmd2.CompletionMode.CUSTOM,
+ choices=['choice_1', 'choice_2', 'choice_3'],
+ )
except EOFError:
pass
else:
@@ -67,8 +73,12 @@ class ReadInputApp(cmd2.Cmd):
"""Call read_input to use custom history and choices provider function"""
self.poutput("Tab completing with choices from provider function and using custom history")
try:
- input_str = self.read_input("> ", history=self.custom_history, completion_mode=cmd2.CompletionMode.CUSTOM,
- choices_provider=ReadInputApp.choices_provider)
+ input_str = self.read_input(
+ "> ",
+ history=self.custom_history,
+ completion_mode=cmd2.CompletionMode.CUSTOM,
+ choices_provider=ReadInputApp.choices_provider,
+ )
except EOFError:
pass
else:
@@ -79,8 +89,9 @@ class ReadInputApp(cmd2.Cmd):
"""all read_input to use custom history and completer function"""
self.poutput("Tab completing paths and using custom history")
try:
- input_str = self.read_input("> ", history=self.custom_history, completion_mode=cmd2.CompletionMode.CUSTOM,
- completer=cmd2.Cmd.path_complete)
+ input_str = self.read_input(
+ "> ", history=self.custom_history, completion_mode=cmd2.CompletionMode.CUSTOM, completer=cmd2.Cmd.path_complete
+ )
self.custom_history.append(input_str)
except EOFError:
pass
@@ -90,16 +101,16 @@ class ReadInputApp(cmd2.Cmd):
"""Call read_input to use a custom history and an argument parser"""
parser = cmd2.Cmd2ArgumentParser(prog='', description="An example parser")
parser.add_argument('-o', '--option', help="an optional arg")
- parser.add_argument('arg_1', help="a choice for this arg", metavar='arg_1',
- choices=['my_choice', 'your_choice'])
+ parser.add_argument('arg_1', help="a choice for this arg", metavar='arg_1', choices=['my_choice', 'your_choice'])
parser.add_argument('arg_2', help="path of something", completer=cmd2.Cmd.path_complete)
self.poutput("Tab completing with argument parser and using custom history")
self.poutput(parser.format_usage())
try:
- input_str = self.read_input("> ", history=self.custom_history, completion_mode=cmd2.CompletionMode.CUSTOM,
- parser=parser)
+ input_str = self.read_input(
+ "> ", history=self.custom_history, completion_mode=cmd2.CompletionMode.CUSTOM, parser=parser
+ )
except EOFError:
pass
else:
@@ -108,5 +119,6 @@ class ReadInputApp(cmd2.Cmd):
if __name__ == '__main__':
import sys
+
app = ReadInputApp()
sys.exit(app.cmdloop())
diff --git a/setup.cfg b/setup.cfg
index a01d2f86..b405af4e 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -35,5 +35,5 @@ use_parentheses = true
[doc8]
ignore-path=docs/_build,.git,.idea,.pytest_cache,.tox,.nox,.venv,.vscode,build,cmd2,examples,tests,cmd2.egg-info,dist,htmlcov,__pycache__,*.egg,plugins
-max-line-length=117
+max-line-length=120
verbose=0
diff --git a/tests/test_argparse_completer.py b/tests/test_argparse_completer.py
index f3f37c4e..efda7660 100644
--- a/tests/test_argparse_completer.py
+++ b/tests/test_argparse_completer.py
@@ -122,30 +122,43 @@ class ArgparseCompleterTester(cmd2.Cmd):
choices_parser = Cmd2ArgumentParser()
# Flag args for choices command. Include string and non-string arg types.
- choices_parser.add_argument("-l", "--list", help="a flag populated with a choices list",
- choices=static_choices_list)
- choices_parser.add_argument("-p", "--provider", help="a flag populated with a choices provider",
- choices_provider=choices_provider)
- choices_parser.add_argument('-d', "--desc_header", help='this arg has a descriptive header',
- choices_provider=completion_item_method,
- descriptive_header=CUSTOM_DESC_HEADER)
- choices_parser.add_argument('-n', "--no_header", help='this arg has no descriptive header',
- choices_provider=completion_item_method, metavar=STR_METAVAR)
- choices_parser.add_argument('-t', "--tuple_metavar", help='this arg has tuple for a metavar',
- choices_provider=completion_item_method, metavar=TUPLE_METAVAR,
- nargs=argparse.ONE_OR_MORE)
- choices_parser.add_argument('-i', '--int', type=int, help='a flag with an int type',
- choices=int_choices)
+ choices_parser.add_argument("-l", "--list", help="a flag populated with a choices list", choices=static_choices_list)
+ choices_parser.add_argument(
+ "-p", "--provider", help="a flag populated with a choices provider", choices_provider=choices_provider
+ )
+ choices_parser.add_argument(
+ '-d',
+ "--desc_header",
+ help='this arg has a descriptive header',
+ choices_provider=completion_item_method,
+ descriptive_header=CUSTOM_DESC_HEADER,
+ )
+ choices_parser.add_argument(
+ '-n',
+ "--no_header",
+ help='this arg has no descriptive header',
+ choices_provider=completion_item_method,
+ metavar=STR_METAVAR,
+ )
+ choices_parser.add_argument(
+ '-t',
+ "--tuple_metavar",
+ help='this arg has tuple for a metavar',
+ choices_provider=completion_item_method,
+ metavar=TUPLE_METAVAR,
+ nargs=argparse.ONE_OR_MORE,
+ )
+ choices_parser.add_argument('-i', '--int', type=int, help='a flag with an int type', choices=int_choices)
# Positional args for choices command
- choices_parser.add_argument("list_pos", help="a positional populated with a choices list",
- choices=static_choices_list)
- choices_parser.add_argument("method_pos", help="a positional populated with a choices provider",
- choices_provider=choices_provider)
- choices_parser.add_argument('non_negative_int', type=int, help='a positional with non-negative int choices',
- choices=non_negative_int_choices)
- choices_parser.add_argument('empty_choices', help='a positional with empty choices',
- choices=[])
+ choices_parser.add_argument("list_pos", help="a positional populated with a choices list", choices=static_choices_list)
+ choices_parser.add_argument(
+ "method_pos", help="a positional populated with a choices provider", choices_provider=choices_provider
+ )
+ choices_parser.add_argument(
+ 'non_negative_int', type=int, help='a positional with non-negative int choices', choices=non_negative_int_choices
+ )
+ choices_parser.add_argument('empty_choices', help='a positional with empty choices', choices=[])
@with_argparser(choices_parser)
def do_choices(self, args: argparse.Namespace) -> None:
@@ -170,14 +183,11 @@ class ArgparseCompleterTester(cmd2.Cmd):
completer_parser = Cmd2ArgumentParser()
# Flag args for completer command
- completer_parser.add_argument("-c", "--completer", help="a flag using a completer",
- completer=flag_completer)
+ completer_parser.add_argument("-c", "--completer", help="a flag using a completer", completer=flag_completer)
# Positional args for completer command
- completer_parser.add_argument("pos_1", help="a positional using a completer method",
- completer=pos_1_completer)
- completer_parser.add_argument("pos_2", help="a positional using a completer method",
- completer=pos_2_completer)
+ completer_parser.add_argument("pos_1", help="a positional using a completer method", completer=pos_1_completer)
+ completer_parser.add_argument("pos_2", help="a positional using a completer method", completer=pos_2_completer)
@with_argparser(completer_parser)
def do_completer(self, args: argparse.Namespace) -> None:
@@ -245,10 +255,8 @@ class ArgparseCompleterTester(cmd2.Cmd):
raise CompletionError('choice broke something')
comp_error_parser = Cmd2ArgumentParser()
- comp_error_parser.add_argument('completer_pos', help='positional arg',
- completer=completer_raise_error)
- comp_error_parser.add_argument('--choice', help='flag arg',
- choices_provider=choice_raise_error)
+ comp_error_parser.add_argument('completer_pos', help='positional arg', completer=completer_raise_error)
+ comp_error_parser.add_argument('--choice', help='flag arg', choices_provider=choice_raise_error)
@with_argparser(comp_error_parser)
def do_raise_completion_error(self, args: argparse.Namespace) -> None:
@@ -261,8 +269,9 @@ class ArgparseCompleterTester(cmd2.Cmd):
"""Choices function that receives arg_tokens from ArgparseCompleter"""
return [arg_tokens['parent_arg'][0], arg_tokens['subcommand'][0]]
- def completer_takes_arg_tokens(self, text: str, line: str, begidx: int, endidx: int,
- arg_tokens: argparse.Namespace) -> List[str]:
+ def completer_takes_arg_tokens(
+ self, text: str, line: str, begidx: int, endidx: int, arg_tokens: argparse.Namespace
+ ) -> List[str]:
"""Completer function that receives arg_tokens from ArgparseCompleter"""
match_against = [arg_tokens['parent_arg'][0], arg_tokens['subcommand'][0]]
return self.basic_complete(text, line, begidx, endidx, match_against)
@@ -516,20 +525,24 @@ def test_autcomp_flag_completion(ac_app, command_and_args, text, completion_matc
else:
assert first_match is None
- assert (ac_app.completion_matches == sorted(completion_matches, key=ac_app.default_sort_key) and
- ac_app.display_matches == sorted(display_matches, key=ac_app.default_sort_key))
+ assert ac_app.completion_matches == sorted(
+ completion_matches, key=ac_app.default_sort_key
+ ) and ac_app.display_matches == sorted(display_matches, key=ac_app.default_sort_key)
-@pytest.mark.parametrize('flag, text, completions', [
- ('-l', '', ArgparseCompleterTester.static_choices_list),
- ('--list', 's', ['static', 'stop']),
- ('-p', '', ArgparseCompleterTester.choices_from_provider),
- ('--provider', 'pr', ['provider', 'probably']),
- ('-i', '', ArgparseCompleterTester.int_choices),
- ('--int', '1', ['1 ']),
- ('--int', '-', [-1, -2, -12]),
- ('--int', '-1', [-1, -12])
-])
+@pytest.mark.parametrize(
+ 'flag, text, completions',
+ [
+ ('-l', '', ArgparseCompleterTester.static_choices_list),
+ ('--list', 's', ['static', 'stop']),
+ ('-p', '', ArgparseCompleterTester.choices_from_provider),
+ ('--provider', 'pr', ['provider', 'probably']),
+ ('-i', '', ArgparseCompleterTester.int_choices),
+ ('--int', '1', ['1 ']),
+ ('--int', '-', [-1, -2, -12]),
+ ('--int', '-1', [-1, -12]),
+ ],
+)
def test_autocomp_flag_choices_completion(ac_app, flag, text, completions):
line = 'choices {} {}'.format(flag, text)
endidx = len(line)
@@ -551,15 +564,18 @@ def test_autocomp_flag_choices_completion(ac_app, flag, text, completions):
assert ac_app.completion_matches == completions
-@pytest.mark.parametrize('pos, text, completions', [
- (1, '', ArgparseCompleterTester.static_choices_list),
- (1, 's', ['static', 'stop']),
- (2, '', ArgparseCompleterTester.choices_from_provider),
- (2, 'pr', ['provider', 'probably']),
- (3, '', ArgparseCompleterTester.non_negative_int_choices),
- (3, '2', [2, 22]),
- (4, '', []),
-])
+@pytest.mark.parametrize(
+ 'pos, text, completions',
+ [
+ (1, '', ArgparseCompleterTester.static_choices_list),
+ (1, 's', ['static', 'stop']),
+ (2, '', ArgparseCompleterTester.choices_from_provider),
+ (2, 'pr', ['provider', 'probably']),
+ (3, '', ArgparseCompleterTester.non_negative_int_choices),
+ (3, '2', [2, 22]),
+ (4, '', []),
+ ],
+)
def test_autocomp_positional_choices_completion(ac_app, pos, text, completions):
# Generate line were preceding positionals are already filled
line = 'choices {} {}'.format('foo ' * (pos - 1), text)
@@ -603,10 +619,10 @@ def test_flag_sorting(ac_app):
assert first_match is not None and ac_app.completion_matches == option_strings
-@pytest.mark.parametrize('flag, text, completions', [
- ('-c', '', ArgparseCompleterTester.completions_for_flag),
- ('--completer', 'f', ['flag', 'fairly'])
-])
+@pytest.mark.parametrize(
+ 'flag, text, completions',
+ [('-c', '', ArgparseCompleterTester.completions_for_flag), ('--completer', 'f', ['flag', 'fairly'])],
+)
def test_autocomp_flag_completers(ac_app, flag, text, completions):
line = 'completer {} {}'.format(flag, text)
endidx = len(line)
@@ -621,12 +637,15 @@ def test_autocomp_flag_completers(ac_app, flag, text, completions):
assert ac_app.completion_matches == sorted(completions, key=ac_app.default_sort_key)
-@pytest.mark.parametrize('pos, text, completions', [
- (1, '', ArgparseCompleterTester.completions_for_pos_1),
- (1, 'p', ['positional_1', 'probably']),
- (2, '', ArgparseCompleterTester.completions_for_pos_2),
- (2, 'm', ['missed', 'me']),
-])
+@pytest.mark.parametrize(
+ 'pos, text, completions',
+ [
+ (1, '', ArgparseCompleterTester.completions_for_pos_1),
+ (1, 'p', ['positional_1', 'probably']),
+ (2, '', ArgparseCompleterTester.completions_for_pos_2),
+ (2, 'm', ['missed', 'me']),
+ ],
+)
def test_autocomp_positional_completers(ac_app, pos, text, completions):
# Generate line were preceding positionals are already filled
line = 'completer {} {}'.format('foo ' * (pos - 1), text)
@@ -705,71 +724,57 @@ def test_completion_items(ac_app, num_aliases, show_description):
assert ('help' in ac_app.display_matches[0]) == show_description
-@pytest.mark.parametrize('args, completions', [
- # Flag with nargs = 2
- ('--set_value', ArgparseCompleterTester.set_value_choices),
- ('--set_value set', ['value', 'choices']),
-
- # Both args are filled. At positional arg now.
- ('--set_value set value', ArgparseCompleterTester.positional_choices),
-
- # Using the flag again will reset the choices available
- ('--set_value set value --set_value', ArgparseCompleterTester.set_value_choices),
-
- # Flag with nargs = ONE_OR_MORE
- ('--one_or_more', ArgparseCompleterTester.one_or_more_choices),
- ('--one_or_more one', ['or', 'more', 'choices']),
-
- # Flag with nargs = OPTIONAL
- ('--optional', ArgparseCompleterTester.optional_choices),
-
- # Only one arg allowed for an OPTIONAL. At positional now.
- ('--optional optional', ArgparseCompleterTester.positional_choices),
-
- # Flag with nargs range (1, 2)
- ('--range', ArgparseCompleterTester.range_choices),
- ('--range some', ['range', 'choices']),
-
- # Already used 2 args so at positional
- ('--range some range', ArgparseCompleterTester.positional_choices),
-
- # Flag with nargs = REMAINDER
- ('--remainder', ArgparseCompleterTester.remainder_choices),
- ('--remainder remainder ', ['choices ']),
-
- # No more flags can appear after a REMAINDER flag)
- ('--remainder choices --set_value', ['remainder ']),
-
- # Double dash ends the current flag
- ('--range choice --', ArgparseCompleterTester.positional_choices),
-
- # Double dash ends a REMAINDER flag
- ('--remainder remainder --', ArgparseCompleterTester.positional_choices),
-
- # No more flags after a double dash
- ('-- --one_or_more ', ArgparseCompleterTester.positional_choices),
-
- # Consume positional
- ('', ArgparseCompleterTester.positional_choices),
- ('positional', ['the', 'choices']),
-
- # Intermixed flag and positional
- ('positional --set_value', ArgparseCompleterTester.set_value_choices),
- ('positional --set_value set', ['choices', 'value']),
-
- # Intermixed flag and positional with flag finishing
- ('positional --set_value set value', ['the', 'choices']),
- ('positional --range choice --', ['the', 'choices']),
-
- # REMAINDER positional
- ('the positional', ArgparseCompleterTester.remainder_choices),
- ('the positional remainder', ['choices ']),
- ('the positional remainder choices', []),
-
- # REMAINDER positional. Flags don't work in REMAINDER
- ('the positional --set_value', ArgparseCompleterTester.remainder_choices),
- ('the positional remainder --set_value', ['choices '])
-])
+@pytest.mark.parametrize(
+ 'args, completions',
+ [
+ # Flag with nargs = 2
+ ('--set_value', ArgparseCompleterTester.set_value_choices),
+ ('--set_value set', ['value', 'choices']),
+ # Both args are filled. At positional arg now.
+ ('--set_value set value', ArgparseCompleterTester.positional_choices),
+ # Using the flag again will reset the choices available
+ ('--set_value set value --set_value', ArgparseCompleterTester.set_value_choices),
+ # Flag with nargs = ONE_OR_MORE
+ ('--one_or_more', ArgparseCompleterTester.one_or_more_choices),
+ ('--one_or_more one', ['or', 'more', 'choices']),
+ # Flag with nargs = OPTIONAL
+ ('--optional', ArgparseCompleterTester.optional_choices),
+ # Only one arg allowed for an OPTIONAL. At positional now.
+ ('--optional optional', ArgparseCompleterTester.positional_choices),
+ # Flag with nargs range (1, 2)
+ ('--range', ArgparseCompleterTester.range_choices),
+ ('--range some', ['range', 'choices']),
+ # Already used 2 args so at positional
+ ('--range some range', ArgparseCompleterTester.positional_choices),
+ # Flag with nargs = REMAINDER
+ ('--remainder', ArgparseCompleterTester.remainder_choices),
+ ('--remainder remainder ', ['choices ']),
+ # No more flags can appear after a REMAINDER flag)
+ ('--remainder choices --set_value', ['remainder ']),
+ # Double dash ends the current flag
+ ('--range choice --', ArgparseCompleterTester.positional_choices),
+ # Double dash ends a REMAINDER flag
+ ('--remainder remainder --', ArgparseCompleterTester.positional_choices),
+ # No more flags after a double dash
+ ('-- --one_or_more ', ArgparseCompleterTester.positional_choices),
+ # Consume positional
+ ('', ArgparseCompleterTester.positional_choices),
+ ('positional', ['the', 'choices']),
+ # Intermixed flag and positional
+ ('positional --set_value', ArgparseCompleterTester.set_value_choices),
+ ('positional --set_value set', ['choices', 'value']),
+ # Intermixed flag and positional with flag finishing
+ ('positional --set_value set value', ['the', 'choices']),
+ ('positional --range choice --', ['the', 'choices']),
+ # REMAINDER positional
+ ('the positional', ArgparseCompleterTester.remainder_choices),
+ ('the positional remainder', ['choices ']),
+ ('the positional remainder choices', []),
+ # REMAINDER positional. Flags don't work in REMAINDER
+ ('the positional --set_value', ArgparseCompleterTester.remainder_choices),
+ ('the positional remainder --set_value', ['choices ']),
+ ],
+)
def test_autcomp_nargs(ac_app, args, completions):
text = ''
line = 'nargs {} {}'.format(args, text)
@@ -1105,10 +1110,7 @@ def test_complete_command_help_no_tokens(ac_app):
assert not completions
-@pytest.mark.parametrize('flag, completions', [
- ('--provider', standalone_choices),
- ('--completer', standalone_completions)
-])
+@pytest.mark.parametrize('flag, completions', [('--provider', standalone_choices), ('--completer', standalone_completions)])
def test_complete_standalone(ac_app, flag, completions):
text = ''
line = 'standalone {} {}'.format(flag, text)
diff --git a/tests/test_argparse_custom.py b/tests/test_argparse_custom.py
index 2f2ee777..dcfb7d9f 100644
--- a/tests/test_argparse_custom.py
+++ b/tests/test_argparse_custom.py
@@ -48,11 +48,14 @@ def fake_func():
pass
-@pytest.mark.parametrize('kwargs, is_valid', [
- ({'choices_provider': fake_func}, True),
- ({'completer': fake_func}, True),
- ({'choices_provider': fake_func, 'completer': fake_func}, False),
-])
+@pytest.mark.parametrize(
+ 'kwargs, is_valid',
+ [
+ ({'choices_provider': fake_func}, True),
+ ({'completer': fake_func}, True),
+ ({'choices_provider': fake_func, 'completer': fake_func}, False),
+ ],
+)
def test_apcustom_choices_callable_count(kwargs, is_valid):
parser = Cmd2ArgumentParser()
try:
@@ -63,10 +66,7 @@ def test_apcustom_choices_callable_count(kwargs, is_valid):
assert 'Only one of the following parameters' in str(ex)
-@pytest.mark.parametrize('kwargs', [
- ({'choices_provider': fake_func}),
- ({'completer': fake_func})
-])
+@pytest.mark.parametrize('kwargs', [({'choices_provider': fake_func}), ({'completer': fake_func})])
def test_apcustom_no_choices_callables_alongside_choices(kwargs):
with pytest.raises(TypeError) as excinfo:
parser = Cmd2ArgumentParser()
@@ -74,10 +74,7 @@ def test_apcustom_no_choices_callables_alongside_choices(kwargs):
assert 'None of the following parameters can be used alongside a choices parameter' in str(excinfo.value)
-@pytest.mark.parametrize('kwargs', [
- ({'choices_provider': fake_func}),
- ({'completer': fake_func})
-])
+@pytest.mark.parametrize('kwargs', [({'choices_provider': fake_func}), ({'completer': fake_func})])
def test_apcustom_no_choices_callables_when_nargs_is_0(kwargs):
with pytest.raises(TypeError) as excinfo:
parser = Cmd2ArgumentParser()
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index f94c0fb0..e719851e 100755
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -1590,6 +1590,7 @@ def test_read_input_rawinput_true(capsys, monkeypatch):
# Run custom history code
import readline
+
readline.add_history('old_history')
custom_history = ['cmd1', 'cmd2']
line = app.read_input(prompt_str, history=custom_history, completion_mode=cmd2.CompletionMode.NONE)
@@ -1605,23 +1606,21 @@ def test_read_input_rawinput_true(capsys, monkeypatch):
# custom choices
custom_choices = ['choice1', 'choice2']
- line = app.read_input(prompt_str, completion_mode=cmd2.CompletionMode.CUSTOM,
- choices=custom_choices)
+ line = app.read_input(prompt_str, completion_mode=cmd2.CompletionMode.CUSTOM, choices=custom_choices)
assert line == input_str
# custom choices_provider
- line = app.read_input(prompt_str, completion_mode=cmd2.CompletionMode.CUSTOM,
- choices_provider=cmd2.Cmd.get_all_commands)
+ line = app.read_input(
+ prompt_str, completion_mode=cmd2.CompletionMode.CUSTOM, choices_provider=cmd2.Cmd.get_all_commands
+ )
assert line == input_str
# custom completer
- line = app.read_input(prompt_str, completion_mode=cmd2.CompletionMode.CUSTOM,
- completer=cmd2.Cmd.path_complete)
+ line = app.read_input(prompt_str, completion_mode=cmd2.CompletionMode.CUSTOM, completer=cmd2.Cmd.path_complete)
assert line == input_str
# custom parser
- line = app.read_input(prompt_str, completion_mode=cmd2.CompletionMode.CUSTOM,
- parser=cmd2.Cmd2ArgumentParser())
+ line = app.read_input(prompt_str, completion_mode=cmd2.CompletionMode.CUSTOM, parser=cmd2.Cmd2ArgumentParser())
assert line == input_str
# isatty is False
@@ -1832,6 +1831,7 @@ def test_alias_create(base_app):
out, err = run_cmd(base_app, 'alias list fake')
assert out == normalize('alias create fake help')
+
def test_alias_create_with_quoted_tokens(base_app):
"""Demonstrate that quotes in alias value will be preserved"""
create_command = 'alias create fake help ">" "out file.txt" ";"'
@@ -1947,6 +1947,7 @@ def test_macro_create(base_app):
out, err = run_cmd(base_app, 'macro list fake')
assert out == normalize('macro create fake help')
+
def test_macro_create_with_quoted_tokens(base_app):
"""Demonstrate that quotes in macro value will be preserved"""
create_command = 'macro create fake help ">" "out file.txt" ";"'
diff --git a/tests/test_completion.py b/tests/test_completion.py
index 1a8e5c4d..6a6e2eff 100755
--- a/tests/test_completion.py
+++ b/tests/test_completion.py
@@ -69,8 +69,9 @@ class CompletionsExample(cmd2.Cmd):
def __init__(self):
cmd2.Cmd.__init__(self, multiline_commands=['test_multiline'])
self.foo = 'bar'
- self.add_settable(utils.Settable('foo', str, description="a settable param",
- completer=CompletionsExample.complete_foo_val))
+ self.add_settable(
+ utils.Settable('foo', str, description="a settable param", completer=CompletionsExample.complete_foo_val)
+ )
def do_test_basic(self, args):
pass
@@ -913,6 +914,7 @@ def test_no_completer(cmd2_app):
first_match = complete_tester(text, line, begidx, endidx, cmd2_app)
assert first_match is not None and cmd2_app.completion_matches == expected
+
def test_wordbreak_in_command(cmd2_app):
text = ''
line = '"{}'.format(text)
diff --git a/tests/test_history.py b/tests/test_history.py
index 57bd0d7b..6f1336a8 100755
--- a/tests/test_history.py
+++ b/tests/test_history.py
@@ -34,7 +34,10 @@ except ImportError:
# readline tests
#
def test_readline_remove_history_item(base_app):
- from cmd2.rl_utils import readline
+ from cmd2.rl_utils import (
+ readline,
+ )
+
readline.clear_history()
assert readline.get_current_history_length() == 0
readline.add_history('this is a test')