diff options
Diffstat (limited to 'cmd2/decorators.py')
-rw-r--r-- | cmd2/decorators.py | 67 |
1 files changed, 41 insertions, 26 deletions
diff --git a/cmd2/decorators.py b/cmd2/decorators.py index 4ee61754..208b8e64 100644 --- a/cmd2/decorators.py +++ b/cmd2/decorators.py @@ -28,12 +28,16 @@ def with_category(category: str) -> Callable: For an alternative approach to categorizing commands using a function, see :func:`~cmd2.utils.categorize` """ + def cat_decorator(func): from .utils import categorize + categorize(func, category) return func + return cat_decorator + ########################## # The _parse_positionals and _arg_swap functions allow for additional positional args to be preserved # in cmd2 command functions/callables. As long as the 2-ple of arguments we expect to be there can be @@ -50,6 +54,7 @@ def _parse_positionals(args: Tuple) -> Tuple[Union['cmd2.Cmd', 'cmd2.CommandSet' """ for pos, arg in enumerate(args): from cmd2 import Cmd, CommandSet + if (isinstance(arg, Cmd) or isinstance(arg, CommandSet)) and len(args) > pos: if isinstance(arg, CommandSet): arg = arg._cmd @@ -72,7 +77,7 @@ def _arg_swap(args: Union[Tuple[Any], List[Any]], search_arg: Any, *replace_arg: """ index = args.index(search_arg) args_list = list(args) - args_list[index:index + 1] = replace_arg + args_list[index : index + 1] = replace_arg return args_list @@ -109,13 +114,11 @@ def with_argument_list(*args: List[Callable], preserve_quotes: bool = False) -> :return: return value of command function """ cmd2_app, statement = _parse_positionals(args) - _, parsed_arglist = cmd2_app.statement_parser.get_command_arg_list(command_name, - statement, - preserve_quotes) + _, parsed_arglist = cmd2_app.statement_parser.get_command_arg_list(command_name, statement, preserve_quotes) args_list = _arg_swap(args, statement, parsed_arglist) return func(*args_list, **kwargs) - command_name = func.__name__[len(constants.COMMAND_FUNC_PREFIX):] + command_name = func.__name__[len(constants.COMMAND_FUNC_PREFIX) :] cmd_wrapper.__doc__ = func.__doc__ return cmd_wrapper @@ -170,10 +173,12 @@ def _set_parser_prog(parser: argparse.ArgumentParser, prog: str): break -def with_argparser_and_unknown_args(parser: argparse.ArgumentParser, *, - ns_provider: Optional[Callable[..., argparse.Namespace]] = None, - preserve_quotes: bool = False) -> \ - Callable[[argparse.Namespace, List], Optional[bool]]: +def with_argparser_and_unknown_args( + parser: argparse.ArgumentParser, + *, + ns_provider: Optional[Callable[..., argparse.Namespace]] = None, + preserve_quotes: bool = False +) -> Callable[[argparse.Namespace, List], Optional[bool]]: """ Deprecated decorator. Use `with_argparser(parser, with_unknown_args=True)` instead. @@ -207,16 +212,23 @@ def with_argparser_and_unknown_args(parser: argparse.ArgumentParser, *, >>> self.poutput('unknowns: {}'.format(unknown)) """ import warnings - warnings.warn('This decorator will be deprecated. Use `with_argparser(parser, with_unknown_args=True)`.', - PendingDeprecationWarning, stacklevel=2) + + warnings.warn( + 'This decorator will be deprecated. Use `with_argparser(parser, with_unknown_args=True)`.', + PendingDeprecationWarning, + stacklevel=2, + ) return with_argparser(parser, ns_provider=ns_provider, preserve_quotes=preserve_quotes, with_unknown_args=True) -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. @@ -277,9 +289,9 @@ def with_argparser(parser: argparse.ArgumentParser, *, :raises: Cmd2ArgparseError if argparse has error parsing command line """ cmd2_app, statement_arg = _parse_positionals(args) - statement, parsed_arglist = cmd2_app.statement_parser.get_command_arg_list(command_name, - statement_arg, - preserve_quotes) + statement, parsed_arglist = cmd2_app.statement_parser.get_command_arg_list( + command_name, statement_arg, preserve_quotes + ) if ns_provider is None: namespace = None @@ -294,7 +306,7 @@ def with_argparser(parser: argparse.ArgumentParser, *, if with_unknown_args: new_args = parser.parse_known_args(parsed_arglist, namespace) else: - new_args = (parser.parse_args(parsed_arglist, namespace), ) + new_args = (parser.parse_args(parsed_arglist, namespace),) ns = new_args[0] except SystemExit: raise Cmd2ArgparseError @@ -318,7 +330,7 @@ def with_argparser(parser: argparse.ArgumentParser, *, return func(*args_list, **kwargs) # argparser defaults the program name to sys.argv[0], but we want it to be the name of our command - command_name = func.__name__[len(constants.COMMAND_FUNC_PREFIX):] + command_name = func.__name__[len(constants.COMMAND_FUNC_PREFIX) :] _set_parser_prog(parser, command_name) # If the description has not been set, then use the method docstring if one exists @@ -338,12 +350,14 @@ def with_argparser(parser: argparse.ArgumentParser, *, return arg_decorator -def as_subcommand_to(command: str, - subcommand: str, - parser: argparse.ArgumentParser, - *, - help: Optional[str] = None, - aliases: Iterable[str] = None) -> Callable[[argparse.Namespace], Optional[bool]]: +def as_subcommand_to( + command: str, + subcommand: str, + parser: argparse.ArgumentParser, + *, + help: Optional[str] = None, + aliases: Iterable[str] = None +) -> Callable[[argparse.Namespace], Optional[bool]]: """ Tag this method as a subcommand to an existing argparse decorated command. @@ -356,6 +370,7 @@ def as_subcommand_to(command: str, ArgumentParser.add_subparser(). :return: Wrapper function that can receive an argparse.Namespace """ + def arg_decorator(func: Callable): _set_parser_prog(parser, command + ' ' + subcommand) |