Skip to content

Commit 17eefde

Browse files
committed
No longer printing all help text for alias and macro when the subcommand is omitted. Instead allow argparse to handle the error.
1 parent 60ab11c commit 17eefde

File tree

4 files changed

+24
-28
lines changed

4 files changed

+24
-28
lines changed

cmd2/cmd2.py

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2398,7 +2398,8 @@ def _alias_list(self, args: argparse.Namespace) -> None:
23982398
alias_parser = Cmd2ArgumentParser(description=alias_description, epilog=alias_epilog, prog='alias')
23992399

24002400
# Add subcommands to alias
2401-
alias_subparsers = alias_parser.add_subparsers()
2401+
alias_subparsers = alias_parser.add_subparsers(dest='subcommand')
2402+
alias_subparsers.required = True
24022403

24032404
# alias -> create
24042405
alias_create_help = "create or overwrite an alias"
@@ -2453,13 +2454,9 @@ def _alias_list(self, args: argparse.Namespace) -> None:
24532454
@with_argparser(alias_parser, preserve_quotes=True)
24542455
def do_alias(self, args: argparse.Namespace) -> None:
24552456
"""Manage aliases"""
2456-
func = getattr(args, 'func', None)
2457-
if func is not None:
2458-
# Call whatever subcommand function was selected
2459-
func(self, args)
2460-
else:
2461-
# noinspection PyTypeChecker
2462-
self.do_help('alias')
2457+
# Call whatever subcommand function was selected
2458+
func = getattr(args, 'func')
2459+
func(self, args)
24632460

24642461
# ----- Macro subcommand functions -----
24652462

@@ -2578,7 +2575,8 @@ def _macro_list(self, args: argparse.Namespace) -> None:
25782575
macro_parser = Cmd2ArgumentParser(description=macro_description, epilog=macro_epilog, prog='macro')
25792576

25802577
# Add subcommands to macro
2581-
macro_subparsers = macro_parser.add_subparsers()
2578+
macro_subparsers = macro_parser.add_subparsers(dest='subcommand')
2579+
macro_subparsers.required = True
25822580

25832581
# macro -> create
25842582
macro_create_help = "create or overwrite a macro"
@@ -2655,13 +2653,9 @@ def _macro_list(self, args: argparse.Namespace) -> None:
26552653
@with_argparser(macro_parser, preserve_quotes=True)
26562654
def do_macro(self, args: argparse.Namespace) -> None:
26572655
"""Manage macros"""
2658-
func = getattr(args, 'func', None)
2659-
if func is not None:
2660-
# Call whatever subcommand function was selected
2661-
func(self, args)
2662-
else:
2663-
# noinspection PyTypeChecker
2664-
self.do_help('macro')
2656+
# Call whatever subcommand function was selected
2657+
func = getattr(args, 'func')
2658+
func(self, args)
26652659

26662660
def complete_help_command(self, text: str, line: str, begidx: int, endidx: int) -> List[str]:
26672661
"""Completes the command argument of help"""
@@ -2672,9 +2666,9 @@ def complete_help_command(self, text: str, line: str, begidx: int, endidx: int)
26722666
strs_to_match = list(topics | visible_commands)
26732667
return utils.basic_complete(text, line, begidx, endidx, strs_to_match)
26742668

2675-
def complete_help_subcommand(self, text: str, line: str, begidx: int, endidx: int,
2676-
arg_tokens: Dict[str, List[str]]) -> List[str]:
2677-
"""Completes the subcommand argument of help"""
2669+
def complete_help_subcommands(self, text: str, line: str, begidx: int, endidx: int,
2670+
arg_tokens: Dict[str, List[str]]) -> List[str]:
2671+
"""Completes the subcommands argument of help"""
26782672

26792673
# Make sure we have a command whose subcommands we will complete
26802674
command = arg_tokens['command'][0]
@@ -2688,7 +2682,7 @@ def complete_help_subcommand(self, text: str, line: str, begidx: int, endidx: in
26882682
return []
26892683

26902684
# Combine the command and its subcommand tokens for the AutoCompleter
2691-
tokens = [command] + arg_tokens['subcommand']
2685+
tokens = [command] + arg_tokens['subcommands']
26922686

26932687
from .argparse_completer import AutoCompleter
26942688
completer = AutoCompleter(argparser, self)
@@ -2698,8 +2692,8 @@ def complete_help_subcommand(self, text: str, line: str, begidx: int, endidx: in
26982692
"detailed help for a specific command")
26992693
help_parser.add_argument('command', nargs=argparse.OPTIONAL, help="command to retrieve help for",
27002694
completer_method=complete_help_command)
2701-
help_parser.add_argument('subcommand', nargs=argparse.REMAINDER, help="subcommand to retrieve help for",
2702-
completer_method=complete_help_subcommand)
2695+
help_parser.add_argument('subcommands', nargs=argparse.REMAINDER, help="subcommand(s) to retrieve help for",
2696+
completer_method=complete_help_subcommands)
27032697
help_parser.add_argument('-v', '--verbose', action='store_true',
27042698
help="print a list of all commands with descriptions of each")
27052699

@@ -2723,7 +2717,7 @@ def do_help(self, args: argparse.Namespace) -> None:
27232717
if func is not None and argparser is not None:
27242718
from .argparse_completer import AutoCompleter
27252719
completer = AutoCompleter(argparser, self)
2726-
tokens = [args.command] + args.subcommand
2720+
tokens = [args.command] + args.subcommands
27272721

27282722
# Set end to blank so the help output matches how it looks when "command -h" is used
27292723
self.poutput(completer.format_help(tokens), end='')

tests/test_cmd2.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,7 +1620,8 @@ def test_get_settable_completion_items(base_app):
16201620

16211621
def test_alias_no_subcommand(base_app):
16221622
out, err = run_cmd(base_app, 'alias')
1623-
assert "Usage: alias [-h]" in out[0]
1623+
assert "Usage: alias [-h]" in err[0]
1624+
assert "Error: the following arguments are required: subcommand" in err[1]
16241625

16251626
def test_alias_create(base_app):
16261627
# Create the alias
@@ -1713,7 +1714,8 @@ def test_multiple_aliases(base_app):
17131714

17141715
def test_macro_no_subcommand(base_app):
17151716
out, err = run_cmd(base_app, 'macro')
1716-
assert "Usage: macro [-h]" in out[0]
1717+
assert "Usage: macro [-h]" in err[0]
1718+
assert "Error: the following arguments are required: subcommand" in err[1]
17171719

17181720
def test_macro_create(base_app):
17191721
# Create the macro

tests/test_completion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,7 @@ def test_cmd2_help_subcommand_completion_with_flags_before_command(scu_app):
11791179
first_match = complete_tester(text, line, begidx, endidx, scu_app)
11801180
assert first_match is not None and scu_app.completion_matches == ['bar', 'foo', 'sport']
11811181

1182-
def test_complete_help_subcommand_with_blank_command(scu_app):
1182+
def test_complete_help_subcommands_with_blank_command(scu_app):
11831183
text = ''
11841184
line = 'help "" {}'.format(text)
11851185
endidx = len(line)

tests/test_transcript.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,13 +224,13 @@ def test_generate_transcript_stop(capsys):
224224
os.close(fd)
225225

226226
# This should run all commands
227-
commands = ['help', 'alias']
227+
commands = ['help', 'set']
228228
app._generate_transcript(commands, transcript_fname)
229229
_, err = capsys.readouterr()
230230
assert err.startswith("2 commands")
231231

232232
# Since quit returns True for stop, only the first 2 commands will run
233-
commands = ['help', 'quit', 'alias']
233+
commands = ['help', 'quit', 'set']
234234
app._generate_transcript(commands, transcript_fname)
235235
_, err = capsys.readouterr()
236236
assert err.startswith("Command 2 triggered a stop")

0 commit comments

Comments
 (0)