summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2018-03-14 22:32:52 -0400
committerKevin Van Brunt <kmvanbrunt@gmail.com>2018-03-14 22:32:52 -0400
commit365b025be72f2b565919b73646f28b187ec0ded1 (patch)
tree24be9d38e4a6fd457ef6a8945f0b60b5d424e670
parentde0a252cd0f7d65685a103e1f7e8525f1c804e1b (diff)
downloadcmd2-git-365b025be72f2b565919b73646f28b187ec0ded1.tar.gz
No longer need to manually specify subcommand names for tab completion
-rwxr-xr-xcmd2.py24
-rwxr-xr-xexamples/subcommands.py5
-rw-r--r--tests/test_argparse.py5
-rw-r--r--tests/test_completion.py5
4 files changed, 17 insertions, 22 deletions
diff --git a/cmd2.py b/cmd2.py
index 65abd58f..8fb0e668 100755
--- a/cmd2.py
+++ b/cmd2.py
@@ -480,14 +480,15 @@ def with_argument_list(func):
return cmd_wrapper
-def with_argparser_and_unknown_args(argparser, subcommand_names=None):
+def with_argparser_and_unknown_args(argparser):
"""A decorator to alter a cmd2 method to populate its ``args`` argument by parsing arguments with the given
instance of argparse.ArgumentParser, but also returning unknown args as a list.
:param argparser: argparse.ArgumentParser - given instance of ArgumentParser
- :param subcommand_names: List[str] - list of subcommand names for this parser (used for tab-completion)
:return: function that gets passed parsed args and a list of unknown args
"""
+
+ # noinspection PyProtectedMember
def arg_decorator(func):
@functools.wraps(func)
def cmd_wrapper(instance, cmdline):
@@ -499,8 +500,8 @@ def with_argparser_and_unknown_args(argparser, subcommand_names=None):
# we want it to be the name of our command
argparser.prog = func.__name__[3:]
- # put the help message in the method docstring
- if func.__doc__:
+ # If the description has not been set, then use the method docstring if one exists
+ if not argparser.description and func.__doc__:
argparser.description = func.__doc__
cmd_wrapper.__doc__ = argparser.format_help()
@@ -509,7 +510,8 @@ def with_argparser_and_unknown_args(argparser, subcommand_names=None):
cmd_wrapper.__dict__['has_parser'] = True
# If there are subcommands, store their names to support tab-completion of subcommand names
- if subcommand_names is not None:
+ if argparser._subparsers is not None:
+ subcommand_names = argparser._subparsers._group_actions[0]._name_parser_map.keys()
cmd_wrapper.__dict__['subcommand_names'] = subcommand_names
return cmd_wrapper
@@ -517,14 +519,15 @@ def with_argparser_and_unknown_args(argparser, subcommand_names=None):
return arg_decorator
-def with_argparser(argparser, subcommand_names=None):
+def with_argparser(argparser):
"""A decorator to alter a cmd2 method to populate its ``args`` argument by parsing arguments
with the given instance of argparse.ArgumentParser.
:param argparser: argparse.ArgumentParser - given instance of ArgumentParser
- :param subcommand_names: List[str] - list of subcommand names for this parser (used for tab-completion)
:return: function that gets passed parsed args
"""
+
+ # noinspection PyProtectedMember
def arg_decorator(func):
@functools.wraps(func)
def cmd_wrapper(instance, cmdline):
@@ -536,8 +539,8 @@ def with_argparser(argparser, subcommand_names=None):
# we want it to be the name of our command
argparser.prog = func.__name__[3:]
- # put the help message in the method docstring
- if func.__doc__:
+ # If the description has not been set, then use the method docstring if one exists
+ if not argparser.description and func.__doc__:
argparser.description = func.__doc__
cmd_wrapper.__doc__ = argparser.format_help()
@@ -546,7 +549,8 @@ def with_argparser(argparser, subcommand_names=None):
cmd_wrapper.__dict__['has_parser'] = True
# If there are subcommands, store their names to support tab-completion of subcommand names
- if subcommand_names is not None:
+ if argparser._subparsers is not None:
+ subcommand_names = argparser._subparsers._group_actions[0]._name_parser_map.keys()
cmd_wrapper.__dict__['subcommand_names'] = subcommand_names
return cmd_wrapper
diff --git a/examples/subcommands.py b/examples/subcommands.py
index a278fd8b..59ebe4cb 100755
--- a/examples/subcommands.py
+++ b/examples/subcommands.py
@@ -42,10 +42,7 @@ class SubcommandsExample(cmd2.Cmd):
parser_bar.add_argument('z', help='string')
parser_bar.set_defaults(func=base_bar)
- # Create a list of subcommand names, which is used to enable tab-completion of sub-commands
- subcommands = ['foo', 'bar']
-
- @with_argparser(base_parser, subcommands)
+ @with_argparser(base_parser)
def do_base(self, args):
"""Base command help"""
try:
diff --git a/tests/test_argparse.py b/tests/test_argparse.py
index d3646046..85b438e2 100644
--- a/tests/test_argparse.py
+++ b/tests/test_argparse.py
@@ -195,10 +195,7 @@ class SubcommandApp(cmd2.Cmd):
parser_bar.add_argument('z', help='string')
parser_bar.set_defaults(func=base_bar)
- # Create a list of subcommand names, which is used to enable tab-completion of sub-commands
- subcommands = ['foo', 'bar']
-
- @cmd2.with_argparser_and_unknown_args(base_parser, subcommands)
+ @cmd2.with_argparser_and_unknown_args(base_parser)
def do_base(self, args, arglist):
"""Base command help"""
try:
diff --git a/tests/test_completion.py b/tests/test_completion.py
index 28dfb1ad..c1111ab9 100644
--- a/tests/test_completion.py
+++ b/tests/test_completion.py
@@ -615,10 +615,7 @@ class SubcommandsExample(cmd2.Cmd):
parser_bar.add_argument('z', help='string')
parser_bar.set_defaults(func=base_bar)
- # Create a list of subcommand names, which is used to enable tab-completion of sub-commands
- subcommands = ['foo', 'bar']
-
- @cmd2.with_argparser(base_parser, subcommands)
+ @cmd2.with_argparser(base_parser)
def do_base(self, args):
"""Base command help"""
try: