diff options
author | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2019-08-27 00:24:29 -0400 |
---|---|---|
committer | Kevin Van Brunt <kmvanbrunt@gmail.com> | 2019-08-27 00:24:29 -0400 |
commit | 33adefc98a07c8d2d0617076de29c52dbd3b4e19 (patch) | |
tree | 1ef18d9536345c21326c9044b8471361c75edc72 /cmd2 | |
parent | 6af36b1753e0f70597def2210bd2b1279a44c188 (diff) | |
download | cmd2-git-33adefc98a07c8d2d0617076de29c52dbd3b4e19.tar.gz |
AutoCompleter only passes parsed_args to choices/completer functions that have an argument called 'parsed_args'
Diffstat (limited to 'cmd2')
-rw-r--r-- | cmd2/argparse_completer.py | 32 | ||||
-rw-r--r-- | cmd2/argparse_custom.py | 6 | ||||
-rwxr-xr-x | cmd2/cmd2.py | 27 | ||||
-rw-r--r-- | cmd2/utils.py | 3 |
4 files changed, 34 insertions, 34 deletions
diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py index 20cc08c3..90d9fcd0 100644 --- a/cmd2/argparse_completer.py +++ b/cmd2/argparse_completer.py @@ -7,6 +7,7 @@ See the header of argparse_custom.py for instructions on how to use these featur """ import argparse +import inspect import numbers import shutil from typing import Dict, List, Union @@ -21,6 +22,10 @@ from .rl_utils import rl_force_redisplay # If no descriptive header is supplied, then this will be used instead DEFAULT_DESCRIPTIVE_HEADER = 'Description' +# Name of the choice/completer function argument that, if present, will be passed a Namespace of +# parsed command line tokens prior to the token being completed +PARSED_ARGS = 'parsed_args' + def _single_prefix_char(token: str, parser: argparse.ArgumentParser) -> bool: """Returns if a token is just a single flag prefix character""" @@ -443,30 +448,31 @@ class AutoCompleter(object): if arg_choices is None: return [] - # Convert consumed_arg_values into an argparse Namespace - parsed_args = argparse.Namespace() - for action, tokens in consumed_arg_values.items(): - setattr(parsed_args, action.dest, tokens) - parsed_args.__parser__ = self._parser - - # Arguments to completer/choices functions + # Set up arguments being passed to any completer/choices function args = [] - kwargs = {'parsed_args': parsed_args} + kwargs = {} + if isinstance(arg_choices, ChoicesCallable): + if arg_choices.is_method: + args.append(self._cmd2_app) + + to_call_params = inspect.signature(arg_choices.to_call).parameters + if PARSED_ARGS in to_call_params: + # Convert consumed_arg_values into an argparse Namespace + parsed_args = argparse.Namespace() + for action, tokens in consumed_arg_values.items(): + setattr(parsed_args, action.dest, tokens) + parsed_args.__parser__ = self._parser + kwargs[PARSED_ARGS] = parsed_args # Check if the argument uses a specific tab completion function to provide its choices if isinstance(arg_choices, ChoicesCallable) and arg_choices.is_completer: - if arg_choices.is_method: - args.append(self._cmd2_app) args.extend([text, line, begidx, endidx]) - results = arg_choices.to_call(*args, **kwargs) # Otherwise use basic_complete on the choices else: # Check if the choices come from a function if isinstance(arg_choices, ChoicesCallable) and not arg_choices.is_completer: - if arg_choices.is_method: - args.append(self._cmd2_app) arg_choices = arg_choices.to_call(*args, **kwargs) # Since arg_choices can be any iterable type, convert to a list diff --git a/cmd2/argparse_custom.py b/cmd2/argparse_custom.py index 56fb57ea..5071989d 100644 --- a/cmd2/argparse_custom.py +++ b/cmd2/argparse_custom.py @@ -44,7 +44,7 @@ Tab Completion: generated when the user hits tab. Example: - def my_choices_function(**kwargs): + def my_choices_function(): ... return my_generated_list @@ -56,7 +56,7 @@ Tab Completion: cases where the list of choices being generated relies on state data of the cmd2-based app Example: - def my_choices_method(self, **kwargs): + def my_choices_method(self): ... return my_generated_list @@ -66,7 +66,7 @@ Tab Completion: function. completer_method should be used in those cases. Example: - def my_completer_function(text, line, begidx, endidx, **kwargs): + def my_completer_function(text, line, begidx, endidx): ... return completions parser.add_argument('-o', '--options', completer_function=my_completer_function) diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index 326a0111..900a4c75 100755 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -851,7 +851,7 @@ class Cmd(cmd.Cmd): return tokens, raw_tokens def delimiter_complete(self, text: str, line: str, begidx: int, endidx: int, - match_against: Iterable, delimiter: str, **_kwargs) -> List[str]: + 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. @@ -882,7 +882,6 @@ class Cmd(cmd.Cmd): :param endidx: the ending index of the prefix text :param match_against: the list being matched against :param delimiter: what delimits each portion of the matches (ex: paths are delimited by a slash) - :param _kwargs: a placeholder that handles the case when AutoCompleter passes keyword args :return: a list of possible tab completions """ matches = utils.basic_complete(text, line, begidx, endidx, match_against) @@ -914,7 +913,7 @@ class Cmd(cmd.Cmd): def flag_based_complete(self, text: str, line: str, begidx: int, endidx: int, flag_dict: Dict[str, Union[Iterable, Callable]], *, - all_else: Union[None, Iterable, Callable] = None, **_kwargs) -> List[str]: + all_else: Union[None, Iterable, Callable] = None) -> List[str]: """Tab completes based on a particular flag preceding the token being completed. :param text: the string prefix we are attempting to match (all matches must begin with it) @@ -928,7 +927,6 @@ class Cmd(cmd.Cmd): 1. iterable list of strings to match against (dictionaries, lists, etc.) 2. function that performs tab completion (ex: path_complete) :param all_else: an optional parameter for tab completing any token that isn't preceded by a flag in flag_dict - :param _kwargs: a placeholder that handles the case when AutoCompleter passes keyword args :return: a list of possible tab completions """ # Get all tokens through the one being completed @@ -957,7 +955,7 @@ class Cmd(cmd.Cmd): def index_based_complete(self, text: str, line: str, begidx: int, endidx: int, index_dict: Mapping[int, Union[Iterable, Callable]], *, - all_else: Union[None, Iterable, Callable] = None, **_kwargs) -> List[str]: + all_else: Union[None, Iterable, Callable] = None) -> List[str]: """Tab completes based on a fixed position in the input string. :param text: the string prefix we are attempting to match (all matches must begin with it) @@ -971,7 +969,6 @@ class Cmd(cmd.Cmd): 1. iterable list of strings to match against (dictionaries, lists, etc.) 2. function that performs tab completion (ex: path_complete) :param all_else: an optional parameter for tab completing any token that isn't at an index in index_dict - :param _kwargs: a placeholder that handles the case when AutoCompleter passes keyword args :return: a list of possible tab completions """ # Get all tokens through the one being completed @@ -1002,7 +999,7 @@ class Cmd(cmd.Cmd): # noinspection PyUnusedLocal def path_complete(self, text: str, line: str, begidx: int, endidx: int, *, - path_filter: Optional[Callable[[str], bool]] = None, **_kwargs) -> List[str]: + path_filter: Optional[Callable[[str], bool]] = None) -> List[str]: """Performs completion of local file system paths :param text: the string prefix we are attempting to match (all matches must begin with it) @@ -1012,7 +1009,6 @@ class Cmd(cmd.Cmd): :param path_filter: optional filter function that determines if a path belongs in the results this function takes a path as its argument and returns True if the path should be kept in the results - :param _kwargs: a placeholder that handles the case when AutoCompleter passes keyword args :return: a list of possible tab completions """ @@ -1147,7 +1143,7 @@ class Cmd(cmd.Cmd): return matches def shell_cmd_complete(self, text: str, line: str, begidx: int, endidx: int, *, - complete_blank: bool = False, **_kwargs) -> List[str]: + complete_blank: bool = False) -> List[str]: """Performs completion of executables either in a user's path or a given path :param text: the string prefix we are attempting to match (all matches must begin with it) @@ -1156,7 +1152,6 @@ class Cmd(cmd.Cmd): :param endidx: the ending index of the prefix text :param complete_blank: If True, then a blank will complete all shell commands in a user's path. If False, then no completion is performed. Defaults to False to match Bash shell behavior. - :param _kwargs: a placeholder that handles the case when AutoCompleter passes keyword args :return: a list of possible tab completions """ # Don't tab complete anything if no shell command has been started @@ -1632,19 +1627,19 @@ class Cmd(cmd.Cmd): return commands - def _get_alias_completion_items(self, **_kwargs) -> List[CompletionItem]: + def _get_alias_completion_items(self) -> List[CompletionItem]: """Return list of current alias names and values as CompletionItems""" return [CompletionItem(cur_key, self.aliases[cur_key]) for cur_key in self.aliases] - def _get_macro_completion_items(self, **_kwargs) -> List[CompletionItem]: + def _get_macro_completion_items(self) -> List[CompletionItem]: """Return list of current macro names and values as CompletionItems""" return [CompletionItem(cur_key, self.macros[cur_key].value) for cur_key in self.macros] - def _get_settable_completion_items(self, **_kwargs) -> List[CompletionItem]: + def _get_settable_completion_items(self) -> List[CompletionItem]: """Return list of current settable names and descriptions as CompletionItems""" return [CompletionItem(cur_key, self.settable[cur_key]) for cur_key in self.settable] - def _get_commands_aliases_and_macros_for_completion(self, **_kwargs) -> List[str]: + def _get_commands_aliases_and_macros_for_completion(self) -> List[str]: """Return a list of visible commands, aliases, and macros for tab completion""" visible_commands = set(self.get_visible_commands()) alias_names = set(self.aliases) @@ -2664,7 +2659,7 @@ class Cmd(cmd.Cmd): # noinspection PyTypeChecker self.do_help('macro') - def complete_help_command(self, text: str, line: str, begidx: int, endidx: int, **_kwargs) -> List[str]: + def complete_help_command(self, text: str, line: str, begidx: int, endidx: int) -> List[str]: """Completes the command argument of help""" # Complete token against topics and visible commands @@ -2673,7 +2668,7 @@ class Cmd(cmd.Cmd): strs_to_match = list(topics | visible_commands) return utils.basic_complete(text, line, begidx, endidx, strs_to_match) - def complete_help_subcommand(self, text: str, line: str, begidx: int, endidx: int, *, + def complete_help_subcommand(self, text: str, line: str, begidx: int, endidx: int, parsed_args: argparse.Namespace) -> List[str]: """Completes the subcommand argument of help""" diff --git a/cmd2/utils.py b/cmd2/utils.py index 7ee20e88..d0ce10bc 100644 --- a/cmd2/utils.py +++ b/cmd2/utils.py @@ -624,7 +624,7 @@ class RedirectionSavedState(object): # noinspection PyUnusedLocal -def basic_complete(text: str, line: str, begidx: int, endidx: int, match_against: Iterable, **_kwargs) -> List[str]: +def basic_complete(text: str, line: str, begidx: int, endidx: int, match_against: Iterable) -> List[str]: """ Basic tab completion function that matches against a list of strings without considering line contents or cursor position. The args required by this function are defined in the header of Pythons's cmd.py. @@ -634,7 +634,6 @@ def basic_complete(text: str, line: str, begidx: int, endidx: int, match_against :param begidx: the beginning index of the prefix text :param endidx: the ending index of the prefix text :param match_against: the strings being matched against - :param _kwargs: a placeholder that handles the case when AutoCompleter passes keyword args :return: a list of possible tab completions """ return [cur_match for cur_match in match_against if cur_match.startswith(text)] |