@@ -261,17 +261,24 @@ class LoadableBase(cmd2.CommandSet):
261261 def __init__ (self , dummy ):
262262 super (LoadableBase , self ).__init__ ()
263263 self ._dummy = dummy # prevents autoload
264+ self ._cut_called = False
264265
265266 cut_parser = cmd2 .Cmd2ArgumentParser ('cut' )
266267 cut_subparsers = cut_parser .add_subparsers (title = 'item' , help = 'item to cut' )
267268
269+ def namespace_provider (self ) -> argparse .Namespace :
270+ ns = argparse .Namespace ()
271+ ns .cut_called = self ._cut_called
272+ return ns
273+
268274 @cmd2 .with_argparser (cut_parser )
269275 def do_cut (self , ns : argparse .Namespace ):
270276 """Cut something"""
271277 handler = ns .get_handler ()
272278 if handler is not None :
273279 # Call whatever subcommand function was selected
274280 handler (ns )
281+ self ._cut_called = True
275282 else :
276283 # No subcommand was provided, so call help
277284 self ._cmd .pwarning ('This command does nothing without sub-parsers registered' )
@@ -281,9 +288,13 @@ def do_cut(self, ns: argparse.Namespace):
281288 stir_parser = cmd2 .Cmd2ArgumentParser ('stir' )
282289 stir_subparsers = stir_parser .add_subparsers (title = 'item' , help = 'what to stir' )
283290
284- @cmd2 .with_argparser (stir_parser )
291+ @cmd2 .with_argparser (stir_parser , ns_provider = namespace_provider )
285292 def do_stir (self , ns : argparse .Namespace ):
286293 """Stir something"""
294+ if not ns .cut_called :
295+ self ._cmd .poutput ('Need to cut before stirring' )
296+ return
297+
287298 handler = ns .get_handler ()
288299 if handler is not None :
289300 # Call whatever subcommand function was selected
@@ -371,8 +382,8 @@ def complete_style_arg(self, text: str, line: str, begidx: int, endidx: int) ->
371382 bokchoy_parser .add_argument ('style' , completer_method = complete_style_arg )
372383
373384 @cmd2 .as_subcommand_to ('cut' , 'bokchoy' , bokchoy_parser )
374- def cut_bokchoy (self , _ : cmd2 . Statement ):
375- self ._cmd .poutput ('Bok Choy' )
385+ def cut_bokchoy (self , ns : argparse . Namespace ):
386+ self ._cmd .poutput ('Bok Choy: ' + ns . style )
376387
377388
378389def test_subcommands (command_sets_manual ):
@@ -498,8 +509,6 @@ def test_subcommands(command_sets_manual):
498509
499510def test_nested_subcommands (command_sets_manual ):
500511 base_cmds = LoadableBase (1 )
501- # fruit_cmds = LoadableFruits(1)
502- # veg_cmds = LoadableVegetables(1)
503512 pasta_cmds = LoadablePastaStir (1 )
504513
505514 with pytest .raises (CommandSetRegistrationError ):
@@ -520,13 +529,28 @@ def __init__(self, dummy):
520529 stir_pasta_vigor_parser = cmd2 .Cmd2ArgumentParser ('vigor' , add_help = False )
521530 stir_pasta_vigor_parser .add_argument ('frequency' )
522531
532+ # stir sauce doesn't exist anywhere, this should fail
523533 @cmd2 .as_subcommand_to ('stir sauce' , 'vigorously' , stir_pasta_vigor_parser )
524534 def stir_pasta_vigorously (self , ns : argparse .Namespace ):
525535 self ._cmd .poutput ('stir the pasta vigorously' )
526536
527537 with pytest .raises (CommandSetRegistrationError ):
528538 command_sets_manual .register_command_set (BadNestedSubcommands (1 ))
529539
540+ fruit_cmds = LoadableFruits (1 )
541+ command_sets_manual .register_command_set (fruit_cmds )
542+
543+ # validates custom namespace provider works correctly. Stir command will fail until
544+ # the cut command is called
545+ result = command_sets_manual .app_cmd ('stir pasta vigorously everyminute' )
546+ assert 'Need to cut before stirring' in result .stdout
547+
548+ result = command_sets_manual .app_cmd ('cut banana discs' )
549+ assert 'cutting banana: discs' in result .stdout
550+
551+ result = command_sets_manual .app_cmd ('stir pasta vigorously everyminute' )
552+ assert 'stir the pasta vigorously' in result .stdout
553+
530554
531555class AppWithSubCommands (cmd2 .Cmd ):
532556 """Class for testing usage of `as_subcommand_to` decorator directly in a Cmd2 subclass."""
0 commit comments