@@ -168,7 +168,6 @@ def _ArgsAndFlagsSections(info, spec, metadata):
168
168
"""The "Args and Flags" sections of the help string."""
169
169
args_with_no_defaults = spec .args [:len (spec .args ) - len (spec .defaults )]
170
170
args_with_defaults = spec .args [len (spec .args ) - len (spec .defaults ):]
171
- flags = args_with_defaults + spec .kwonlyargs
172
171
173
172
# Check if positional args are allowed. If not, require flag syntax for args.
174
173
accepts_positional_args = metadata .get (decorators .ACCEPTS_POSITIONAL_ARGS )
@@ -197,10 +196,23 @@ def _ArgsAndFlagsSections(info, spec, metadata):
197
196
('NOTES' , 'You can also use flags syntax for POSITIONAL ARGUMENTS' )
198
197
)
199
198
200
- flag_items = [
201
- _CreateFlagItem (flag , docstring_info )
202
- for flag in flags
199
+ optional_flag_items = [
200
+ _CreateFlagItem (flag , docstring_info , required = False )
201
+ for flag in args_with_defaults
203
202
]
203
+ required_flag_items = [
204
+ _CreateFlagItem (flag , docstring_info , required = True )
205
+ for flag in spec .kwonlyargs
206
+ ]
207
+ flag_items = optional_flag_items + required_flag_items
208
+
209
+ if spec .varkw :
210
+ description = _GetArgDescription (spec .varkw , docstring_info )
211
+ message = ('Additional flags are accepted.'
212
+ if flag_items else
213
+ 'Flags are accepted.' )
214
+ item = _CreateItem (message , description , indent = 4 )
215
+ flag_items .append (item )
204
216
205
217
if flag_items :
206
218
flags_section = ('FLAGS' , '\n ' .join (flag_items ))
@@ -262,7 +274,6 @@ def _GetArgsAndFlagsString(spec, metadata):
262
274
"""
263
275
args_with_no_defaults = spec .args [:len (spec .args ) - len (spec .defaults )]
264
276
args_with_defaults = spec .args [len (spec .args ) - len (spec .defaults ):]
265
- flags = args_with_defaults + spec .kwonlyargs
266
277
267
278
# Check if positional args are allowed. If not, require flag syntax for args.
268
279
accepts_positional_args = metadata .get (decorators .ACCEPTS_POSITIONAL_ARGS )
@@ -279,13 +290,9 @@ def _GetArgsAndFlagsString(spec, metadata):
279
290
for arg in args_with_no_defaults ]
280
291
arg_and_flag_strings .extend (arg_strings )
281
292
282
- flag_string_template = '[--{flag_name}={flag_name_upper}]'
283
- if flags :
284
- for flag in flags :
285
- flag_string = flag_string_template .format (
286
- flag_name = flag ,
287
- flag_name_upper = formatting .Underline (flag .upper ()))
288
- arg_and_flag_strings .append (flag_string )
293
+ # If there are any arguments that are treated as flags:
294
+ if args_with_defaults or spec .kwonlyargs or spec .varkw :
295
+ arg_and_flag_strings .append ('<flags>' )
289
296
290
297
if spec .varargs :
291
298
varargs_string = '[{varargs}]...' .format (
@@ -367,48 +374,51 @@ def _CreateArgItem(arg, docstring_info):
367
374
Returns:
368
375
A string to be used in constructing the help screen for the function.
369
376
"""
370
- description = None
371
- if docstring_info .args :
372
- for arg_in_docstring in docstring_info .args :
373
- if arg_in_docstring .name in (arg , '*' + arg , '**' + arg ):
374
- description = arg_in_docstring .description
377
+ description = _GetArgDescription (arg , docstring_info )
375
378
376
379
arg = arg .upper ()
377
- if description :
378
- return _CreateItem (formatting .BoldUnderline (arg ), description , indent = 4 )
379
- else :
380
- return formatting .BoldUnderline (arg )
380
+ return _CreateItem (formatting.BoldUnderline (arg ), description , indent = 4 )
381
381
382
382
383
- def _CreateFlagItem (flag , docstring_info ):
383
+ def _CreateFlagItem (flag , docstring_info , required = False ):
384
384
"""Returns a string describing a flag using information from the docstring.
385
385
386
386
Args:
387
387
flag: The name of the flag.
388
388
docstring_info: A docstrings.DocstringInfo namedtuple with information about
389
389
the containing function's docstring.
390
+ required: Whether the flag is required. Keyword-only arguments (only in
391
+ Python 3) become required flags, whereas normal keyword arguments become
392
+ optional flags.
390
393
Returns:
391
394
A string to be used in constructing the help screen for the function.
392
395
"""
393
- description = None
394
- if docstring_info .args :
395
- for arg_in_docstring in docstring_info .args :
396
- if arg_in_docstring .name == flag :
397
- description = arg_in_docstring .description
398
- break
396
+ description = _GetArgDescription (flag , docstring_info )
399
397
400
- flag = '--{flag}' .format (flag = formatting .Underline (flag ))
401
- if description :
402
- return _CreateItem (flag , description , indent = 4 )
403
- return flag
398
+ flag_string_template = '--{flag_name}={flag_name_upper}'
399
+ flag = flag_string_template .format (
400
+ flag_name = flag ,
401
+ flag_name_upper = formatting .Underline (flag .upper ()))
402
+ if not required :
403
+ flag += ' (optional)'
404
+ return _CreateItem (flag , description , indent = 4 )
404
405
405
406
406
407
def _CreateItem (name , description , indent = 2 ):
408
+ if not description :
409
+ return name
407
410
return """{name}
408
411
{description}""" .format (name = name ,
409
412
description = formatting .Indent (description , indent ))
410
413
411
414
415
+ def _GetArgDescription (name , docstring_info ):
416
+ if docstring_info .args :
417
+ for arg_in_docstring in docstring_info .args :
418
+ if arg_in_docstring .name in (name , '*' + name , '**' + name ):
419
+ return arg_in_docstring .description
420
+
421
+
412
422
def _GroupUsageDetailsSection (groups ):
413
423
"""Creates a section tuple for the groups section of the usage details."""
414
424
group_item_strings = []
@@ -417,9 +427,8 @@ def _GroupUsageDetailsSection(groups):
417
427
group_item = group_name
418
428
if 'docstring_info' in group_info :
419
429
group_docstring_info = group_info ['docstring_info' ]
420
- if group_docstring_info and group_docstring_info .summary :
421
- group_item = _CreateItem (group_name ,
422
- group_docstring_info .summary )
430
+ if group_docstring_info :
431
+ group_item = _CreateItem (group_name , group_docstring_info .summary )
423
432
group_item_strings .append (group_item )
424
433
return ('GROUPS' , _NewChoicesSection ('GROUP' , group_item_strings ))
425
434
@@ -432,9 +441,8 @@ def _CommandUsageDetailsSection(commands):
432
441
command_item = command_name
433
442
if 'docstring_info' in command_info :
434
443
command_docstring_info = command_info ['docstring_info' ]
435
- if command_docstring_info and command_docstring_info .summary :
436
- command_item = _CreateItem (command_name ,
437
- command_docstring_info .summary )
444
+ if command_docstring_info :
445
+ command_item = _CreateItem (command_name , command_docstring_info .summary )
438
446
command_item_strings .append (command_item )
439
447
return ('COMMANDS' , _NewChoicesSection ('COMMAND' , command_item_strings ))
440
448
@@ -502,14 +510,8 @@ def UsageTextForFunction(component, trace=None, verbose=False):
502
510
command = ''
503
511
504
512
spec = inspectutils .GetFullArgSpec (component )
505
- args = spec .args
506
- if spec .defaults is None :
507
- num_defaults = 0
508
- else :
509
- num_defaults = len (spec .defaults )
510
- args_with_no_defaults = args [:len (args ) - num_defaults ]
511
- args_with_defaults = args [len (args ) - num_defaults :]
512
- flags = args_with_defaults + spec .kwonlyargs
513
+ args_with_no_defaults = spec .args [:len (spec .args ) - len (spec .defaults )]
514
+ args_with_defaults = spec .args [len (spec .args ) - len (spec .defaults ):]
513
515
514
516
# Check if positional args are allowed. If not, show flag syntax for args.
515
517
metadata = decorators .GetMetadata (component )
@@ -520,13 +522,32 @@ def UsageTextForFunction(component, trace=None, verbose=False):
520
522
else :
521
523
items = [arg .upper () for arg in args_with_no_defaults ]
522
524
523
- if flags :
525
+ # If there are any arguments that are treated as flags:
526
+ if args_with_defaults or spec .kwonlyargs or spec .varkw :
524
527
items .append ('<flags>' )
525
- availability_lines = (
526
- '\n Available flags: '
527
- + ' | ' .join ('--' + flag for flag in flags ) + '\n ' )
528
- else :
529
- availability_lines = ''
528
+
529
+ optional_flags = [('--' + flag ) for flag in args_with_defaults ]
530
+ required_flags = [('--' + flag ) for flag in spec .kwonlyargs ]
531
+
532
+ # Flags section:
533
+ availability_lines = []
534
+ if optional_flags :
535
+ availability_lines .append (
536
+ _CreateAvailabilityLine (header = 'Optional flags:' , items = optional_flags ,
537
+ header_indent = 0 ))
538
+ if required_flags :
539
+ availability_lines .append (
540
+ _CreateAvailabilityLine (header = 'Required flags:' , items = required_flags ,
541
+ header_indent = 0 ))
542
+ if spec .varkw :
543
+ additional_flags = ('Additional flags are accepted.'
544
+ if optional_flags or required_flags else
545
+ 'Flags are accepted.' )
546
+ availability_lines .append (additional_flags + '\n ' )
547
+
548
+ if availability_lines :
549
+ # Start the section with blank lines.
550
+ availability_lines .insert (0 , '\n ' )
530
551
531
552
if spec .varargs :
532
553
items .append ('[{varargs}]...' .format (varargs = spec .varargs .upper ()))
@@ -538,7 +559,7 @@ def UsageTextForFunction(component, trace=None, verbose=False):
538
559
return output_template .format (
539
560
current_command = command ,
540
561
args_and_flags = args_and_flags ,
541
- availability_lines = availability_lines ,
562
+ availability_lines = '' . join ( availability_lines ) ,
542
563
hyphen_hyphen = hyphen_hyphen )
543
564
544
565
@@ -576,25 +597,25 @@ def UsageTextForObject(component, trace=None, verbose=False):
576
597
possible_actions .append ('group' )
577
598
groups_text = _CreateAvailabilityLine (
578
599
header = 'available groups:' ,
579
- items = groups )
600
+ items = [ name for name , _ in groups ] )
580
601
availability_lines .append (groups_text )
581
602
if commands :
582
603
possible_actions .append ('command' )
583
604
commands_text = _CreateAvailabilityLine (
584
605
header = 'available commands:' ,
585
- items = commands )
606
+ items = [ name for name , _ in commands ] )
586
607
availability_lines .append (commands_text )
587
608
if values :
588
609
possible_actions .append ('value' )
589
610
values_text = _CreateAvailabilityLine (
590
611
header = 'available values:' ,
591
- items = values )
612
+ items = [ name for name , _ in values ] )
592
613
availability_lines .append (values_text )
593
614
if indexes :
594
615
possible_actions .append ('index' )
595
616
indexes_text = _CreateAvailabilityLine (
596
617
header = 'available indexes:' ,
597
- items = [( indexes , None )] )
618
+ items = indexes )
598
619
availability_lines .append (indexes_text )
599
620
600
621
if possible_actions :
@@ -615,8 +636,7 @@ def _CreateAvailabilityLine(header, items,
615
636
header_indent = 2 , items_indent = 25 ,
616
637
line_length = LINE_LENGTH ):
617
638
items_width = line_length - items_indent
618
- item_names = [item [0 ] for item in items ]
619
- items_text = '\n ' .join (formatting .WrappedJoin (item_names , width = items_width ))
639
+ items_text = '\n ' .join (formatting .WrappedJoin (items , width = items_width ))
620
640
indented_items_text = formatting .Indent (items_text , spaces = items_indent )
621
641
indented_header = formatting .Indent (header , spaces = header_indent )
622
642
return indented_header + indented_items_text [len (indented_header ):] + '\n '
0 commit comments