@@ -261,17 +261,24 @@ class LoadableBase(cmd2.CommandSet):
261
261
def __init__ (self , dummy ):
262
262
super (LoadableBase , self ).__init__ ()
263
263
self ._dummy = dummy # prevents autoload
264
+ self ._cut_called = False
264
265
265
266
cut_parser = cmd2 .Cmd2ArgumentParser ('cut' )
266
267
cut_subparsers = cut_parser .add_subparsers (title = 'item' , help = 'item to cut' )
267
268
269
+ def namespace_provider (self ) -> argparse .Namespace :
270
+ ns = argparse .Namespace ()
271
+ ns .cut_called = self ._cut_called
272
+ return ns
273
+
268
274
@cmd2 .with_argparser (cut_parser )
269
275
def do_cut (self , ns : argparse .Namespace ):
270
276
"""Cut something"""
271
277
handler = ns .get_handler ()
272
278
if handler is not None :
273
279
# Call whatever subcommand function was selected
274
280
handler (ns )
281
+ self ._cut_called = True
275
282
else :
276
283
# No subcommand was provided, so call help
277
284
self ._cmd .pwarning ('This command does nothing without sub-parsers registered' )
@@ -281,9 +288,13 @@ def do_cut(self, ns: argparse.Namespace):
281
288
stir_parser = cmd2 .Cmd2ArgumentParser ('stir' )
282
289
stir_subparsers = stir_parser .add_subparsers (title = 'item' , help = 'what to stir' )
283
290
284
- @cmd2 .with_argparser (stir_parser )
291
+ @cmd2 .with_argparser (stir_parser , ns_provider = namespace_provider )
285
292
def do_stir (self , ns : argparse .Namespace ):
286
293
"""Stir something"""
294
+ if not ns .cut_called :
295
+ self ._cmd .poutput ('Need to cut before stirring' )
296
+ return
297
+
287
298
handler = ns .get_handler ()
288
299
if handler is not None :
289
300
# Call whatever subcommand function was selected
@@ -371,8 +382,8 @@ def complete_style_arg(self, text: str, line: str, begidx: int, endidx: int) ->
371
382
bokchoy_parser .add_argument ('style' , completer_method = complete_style_arg )
372
383
373
384
@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 )
376
387
377
388
378
389
def test_subcommands (command_sets_manual ):
@@ -498,8 +509,6 @@ def test_subcommands(command_sets_manual):
498
509
499
510
def test_nested_subcommands (command_sets_manual ):
500
511
base_cmds = LoadableBase (1 )
501
- # fruit_cmds = LoadableFruits(1)
502
- # veg_cmds = LoadableVegetables(1)
503
512
pasta_cmds = LoadablePastaStir (1 )
504
513
505
514
with pytest .raises (CommandSetRegistrationError ):
@@ -520,13 +529,28 @@ def __init__(self, dummy):
520
529
stir_pasta_vigor_parser = cmd2 .Cmd2ArgumentParser ('vigor' , add_help = False )
521
530
stir_pasta_vigor_parser .add_argument ('frequency' )
522
531
532
+ # stir sauce doesn't exist anywhere, this should fail
523
533
@cmd2 .as_subcommand_to ('stir sauce' , 'vigorously' , stir_pasta_vigor_parser )
524
534
def stir_pasta_vigorously (self , ns : argparse .Namespace ):
525
535
self ._cmd .poutput ('stir the pasta vigorously' )
526
536
527
537
with pytest .raises (CommandSetRegistrationError ):
528
538
command_sets_manual .register_command_set (BadNestedSubcommands (1 ))
529
539
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
+
530
554
531
555
class AppWithSubCommands (cmd2 .Cmd ):
532
556
"""Class for testing usage of `as_subcommand_to` decorator directly in a Cmd2 subclass."""
0 commit comments