3333from __future__ import division
3434from __future__ import print_function
3535
36- import inspect
37-
3836from fire import completion
3937from fire import custom_descriptions
4038from fire import decorators
@@ -319,7 +317,7 @@ def _GetActionsGroupedByKind(component, verbose=False):
319317 values = ActionGroup (name = 'value' , plural = 'values' )
320318 indexes = ActionGroup (name = 'index' , plural = 'indexes' )
321319
322- members = completion ._Members (component , verbose ) # pylint: disable=protected-access
320+ members = completion .VisibleMembers (component , verbose = verbose )
323321 for member_name , member in members :
324322 member_name = str (member_name )
325323 if value_types .IsGroup (member ):
@@ -456,14 +454,7 @@ def _NewChoicesSection(name, choices):
456454
457455
458456def UsageText (component , trace = None , verbose = False ):
459- if inspect .isroutine (component ) or inspect .isclass (component ):
460- return UsageTextForFunction (component , trace , verbose )
461- else :
462- return UsageTextForObject (component , trace , verbose )
463-
464-
465- def UsageTextForFunction (component , trace = None , verbose = False ):
466- """Returns usage text for function objects.
457+ """Returns usage text for the given component.
467458
468459 Args:
469460 component: The component to determine the usage text for.
@@ -473,13 +464,12 @@ def UsageTextForFunction(component, trace=None, verbose=False):
473464 Returns:
474465 String suitable for display in an error screen.
475466 """
476- del verbose # Unused.
477-
478- output_template = """Usage: {current_command} {args_and_flags}
467+ output_template = """Usage: {continued_command}
479468{availability_lines}
480469For detailed information on this command, run:
481- {current_command}{hyphen_hyphen} --help """
470+ {help_command} """
482471
472+ # Get the command so far:
483473 if trace :
484474 command = trace .GetCommand ()
485475 needs_separating_hyphen_hyphen = trace .NeedsSeparatingHyphenHyphen ()
@@ -490,13 +480,67 @@ def UsageTextForFunction(component, trace=None, verbose=False):
490480 if not command :
491481 command = ''
492482
483+ # Build the continuations for the command:
484+ continued_command = command
485+
493486 spec = inspectutils .GetFullArgSpec (component )
487+ metadata = decorators .GetMetadata (component )
488+
489+ # Usage for objects.
490+ actions_grouped_by_kind = _GetActionsGroupedByKind (component , verbose = verbose )
491+ possible_actions = _GetPossibleActions (actions_grouped_by_kind )
492+
493+ continuations = []
494+ if possible_actions :
495+ continuations .append (_GetPossibleActionsUsageString (possible_actions ))
496+
497+ availability_lines = _UsageAvailabilityLines (actions_grouped_by_kind )
498+
499+ if callable (component ):
500+ callable_items = _GetCallableUsageItems (spec , metadata )
501+ continuations .append (' ' .join (callable_items ))
502+ availability_lines .extend (_GetCallableAvailabilityLines (spec ))
503+
504+ if continuations :
505+ continued_command += ' ' + ' | ' .join (continuations )
506+ help_command = (
507+ command
508+ + (' -- ' if needs_separating_hyphen_hyphen else ' ' )
509+ + '--help'
510+ )
511+
512+ return output_template .format (
513+ continued_command = continued_command ,
514+ availability_lines = '' .join (availability_lines ),
515+ help_command = help_command )
516+
517+
518+ def _GetPossibleActionsUsageString (possible_actions ):
519+ if possible_actions :
520+ return '<{actions}>' .format (actions = '|' .join (possible_actions ))
521+ return None
522+
523+
524+ def _UsageAvailabilityLines (actions_grouped_by_kind ):
525+ availability_lines = []
526+ for action_group in actions_grouped_by_kind :
527+ if action_group .members :
528+ availability_line = _CreateAvailabilityLine (
529+ header = 'available {plural}:' .format (plural = action_group .plural ),
530+ items = action_group .names
531+ )
532+ availability_lines .append (availability_line )
533+ return availability_lines
534+
535+
536+ def _GetCallableUsageItems (spec , metadata ):
537+ """A list of elements that comprise the usage summary for a callable."""
494538 args_with_no_defaults = spec .args [:len (spec .args ) - len (spec .defaults )]
495539 args_with_defaults = spec .args [len (spec .args ) - len (spec .defaults ):]
496540
497541 # Check if positional args are allowed. If not, show flag syntax for args.
498- metadata = decorators .GetMetadata (component )
499542 accepts_positional_args = metadata .get (decorators .ACCEPTS_POSITIONAL_ARGS )
543+
500544 if not accepts_positional_args :
501545 items = ['--{arg}={upper}' .format (arg = arg , upper = arg .upper ())
502546 for arg in args_with_no_defaults ]
@@ -507,93 +551,38 @@ def UsageTextForFunction(component, trace=None, verbose=False):
507551 if args_with_defaults or spec .kwonlyargs or spec .varkw :
508552 items .append ('<flags>' )
509553
554+ if spec .varargs :
555+ items .append ('[{varargs}]...' .format (varargs = spec .varargs .upper ()))
556+
557+ return items
558+
559+
560+ def _GetCallableAvailabilityLines (spec ):
561+ """The list of availability lines for a callable for use in a usage string."""
562+ args_with_defaults = spec .args [len (spec .args ) - len (spec .defaults ):]
563+
564+ # TODO(dbieber): Handle args_with_no_defaults if not accepts_positional_args.
510565 optional_flags = [('--' + flag ) for flag in args_with_defaults ]
511566 required_flags = [('--' + flag ) for flag in spec .kwonlyargs ]
512567
513568 # Flags section:
514569 availability_lines = []
515570 if optional_flags :
516571 availability_lines .append (
517- _CreateAvailabilityLine (header = 'Optional flags:' , items = optional_flags ,
518- header_indent = 0 ))
572+ _CreateAvailabilityLine (header = 'optional flags:' , items = optional_flags ,
573+ header_indent = 2 ))
519574 if required_flags :
520575 availability_lines .append (
521- _CreateAvailabilityLine (header = 'Required flags:' , items = required_flags ,
522- header_indent = 0 ))
576+ _CreateAvailabilityLine (header = 'required flags:' , items = required_flags ,
577+ header_indent = 2 ))
523578 if spec .varkw :
524- additional_flags = ('Additional flags are accepted. '
579+ additional_flags = ('additional flags are accepted'
525580 if optional_flags or required_flags else
526- 'Flags are accepted.' )
527- availability_lines .append (additional_flags + '\n ' )
528-
529- if availability_lines :
530- # Start the section with blank lines.
531- availability_lines .insert (0 , '\n ' )
532-
533- if spec .varargs :
534- items .append ('[{varargs}]...' .format (varargs = spec .varargs .upper ()))
535-
536- args_and_flags = ' ' .join (items )
537-
538- hyphen_hyphen = ' --' if needs_separating_hyphen_hyphen else ''
539-
540- return output_template .format (
541- current_command = command ,
542- args_and_flags = args_and_flags ,
543- availability_lines = '' .join (availability_lines ),
544- hyphen_hyphen = hyphen_hyphen )
545-
546-
547- def UsageTextForObject (component , trace = None , verbose = False ):
548- """Returns the usage text for the error screen for an object.
549-
550- Constructs the usage text for the error screen to inform the user about how
551- to use the current component.
552-
553- Args:
554- component: The component to determine the usage text for.
555- trace: The Fire trace object containing all metadata of current execution.
556- verbose: Whether to include private members in the usage text.
557- Returns:
558- String suitable for display in error screen.
559- """
560- output_template = """Usage: {current_command}{possible_actions}
561- {availability_lines}
562- For detailed information on this command, run:
563- {current_command} --help"""
564- if trace :
565- command = trace .GetCommand ()
566- else :
567- command = None
568-
569- if not command :
570- command = ''
571-
572- actions_grouped_by_kind = _GetActionsGroupedByKind (component , verbose = verbose )
573-
574- possible_actions = []
575- availability_lines = []
576- for action_group in actions_grouped_by_kind :
577- if action_group .members :
578- possible_actions .append (action_group .name )
579- availability_line = _CreateAvailabilityLine (
580- header = 'available {plural}:' .format (plural = action_group .plural ),
581- items = action_group .names
582- )
583- availability_lines .append (availability_line )
584-
585- if possible_actions :
586- possible_actions_string = ' <{actions}>' .format (
587- actions = '|' .join (possible_actions ))
588- else :
589- possible_actions_string = ''
590-
591- availability_lines_string = '' .join (availability_lines )
592-
593- return output_template .format (
594- current_command = command ,
595- possible_actions = possible_actions_string ,
596- availability_lines = availability_lines_string )
581+ 'flags are accepted' )
582+ availability_lines .append (
583+ _CreateAvailabilityLine (header = additional_flags , items = [],
584+ header_indent = 2 ))
585+ return availability_lines
597586
598587
599588def _CreateAvailabilityLine (header , items ,
0 commit comments