@@ -233,9 +233,14 @@ def base_bar(self, args):
233233 """bar subcommand of base command"""
234234 self .poutput ('((%s))' % args .z )
235235
236+ def base_helpless (self , args ):
237+ """helpless subcommand of base command"""
238+ self .poutput ('((%s))' % args .z )
239+
236240 # create the top-level parser for the base command
237241 base_parser = argparse .ArgumentParser ()
238- base_subparsers = base_parser .add_subparsers (title = 'subcommands' , help = 'subcommand help' )
242+ base_subparsers = base_parser .add_subparsers (dest = 'subcommand' , metavar = 'SUBCOMMAND' )
243+ base_subparsers .required = True
239244
240245 # create the parser for the "foo" subcommand
241246 parser_foo = base_subparsers .add_parser ('foo' , help = 'foo help' )
@@ -244,20 +249,24 @@ def base_bar(self, args):
244249 parser_foo .set_defaults (func = base_foo )
245250
246251 # create the parser for the "bar" subcommand
247- parser_bar = base_subparsers .add_parser ('bar' , help = 'bar help' )
252+ parser_bar = base_subparsers .add_parser ('bar' , help = 'bar help' , aliases = ['bar_1' , 'bar_2' ])
253+ parser_bar .add_argument ('z' , help = 'string' )
254+ parser_bar .set_defaults (func = base_bar )
255+
256+ # create the parser for the "helpless" subcommand
257+ # This subcommand has aliases and no help text. It exists to prevent changes to _set_parser_prog() which
258+ # use an approach which relies on action._choices_actions list. See comment in that function for more
259+ # details.
260+ parser_bar = base_subparsers .add_parser ('helpless' , aliases = ['helpless_1' , 'helpless_2' ])
248261 parser_bar .add_argument ('z' , help = 'string' )
249262 parser_bar .set_defaults (func = base_bar )
250263
251264 @cmd2 .with_argparser (base_parser )
252265 def do_base (self , args ):
253266 """Base command help"""
254- func = getattr (args , 'func' , None )
255- if func is not None :
256- # Call whatever subcommand function was selected
257- func (self , args )
258- else :
259- # No subcommand was provided, so call help
260- self .do_help ('base' )
267+ # Call whatever subcommand function was selected
268+ func = getattr (args , 'func' )
269+ func (self , args )
261270
262271@pytest .fixture
263272def subcommand_app ():
@@ -277,7 +286,7 @@ def test_subcommand_bar(subcommand_app):
277286def test_subcommand_invalid (subcommand_app ):
278287 out , err = run_cmd (subcommand_app , 'base baz' )
279288 assert err [0 ].startswith ('usage: base' )
280- assert err [1 ].startswith ("base: error: invalid choice: 'baz'" )
289+ assert err [1 ].startswith ("base: error: argument SUBCOMMAND: invalid choice: 'baz'" )
281290
282291def test_subcommand_base_help (subcommand_app ):
283292 out , err = run_cmd (subcommand_app , 'help base' )
@@ -286,11 +295,44 @@ def test_subcommand_base_help(subcommand_app):
286295 assert out [2 ] == 'Base command help'
287296
288297def test_subcommand_help (subcommand_app ):
298+ # foo has no aliases
289299 out , err = run_cmd (subcommand_app , 'help base foo' )
290300 assert out [0 ].startswith ('usage: base foo' )
291301 assert out [1 ] == ''
292302 assert out [2 ] == 'positional arguments:'
293303
304+ # bar has aliases (usage should never show alias name)
305+ out , err = run_cmd (subcommand_app , 'help base bar' )
306+ assert out [0 ].startswith ('usage: base bar' )
307+ assert out [1 ] == ''
308+ assert out [2 ] == 'positional arguments:'
309+
310+ out , err = run_cmd (subcommand_app , 'help base bar_1' )
311+ assert out [0 ].startswith ('usage: base bar' )
312+ assert out [1 ] == ''
313+ assert out [2 ] == 'positional arguments:'
314+
315+ out , err = run_cmd (subcommand_app , 'help base bar_2' )
316+ assert out [0 ].startswith ('usage: base bar' )
317+ assert out [1 ] == ''
318+ assert out [2 ] == 'positional arguments:'
319+
320+ # helpless has aliases and no help text (usage should never show alias name)
321+ out , err = run_cmd (subcommand_app , 'help base helpless' )
322+ assert out [0 ].startswith ('usage: base helpless' )
323+ assert out [1 ] == ''
324+ assert out [2 ] == 'positional arguments:'
325+
326+ out , err = run_cmd (subcommand_app , 'help base helpless_1' )
327+ assert out [0 ].startswith ('usage: base helpless' )
328+ assert out [1 ] == ''
329+ assert out [2 ] == 'positional arguments:'
330+
331+ out , err = run_cmd (subcommand_app , 'help base helpless_2' )
332+ assert out [0 ].startswith ('usage: base helpless' )
333+ assert out [1 ] == ''
334+ assert out [2 ] == 'positional arguments:'
335+
294336
295337def test_subcommand_invalid_help (subcommand_app ):
296338 out , err = run_cmd (subcommand_app , 'help base baz' )
0 commit comments