Search code examples
argparseuser-experience

Format argparse help for positional arguments


Default argparse help output is ugly:

usage: gl.EXE [-h] [--version]
              {track,untrack,status,diff,commit,branch,tag,checkout,merge,resolve,fuse,remote,publish,switch,init,history}
              ...

Gitless - a version control system built on top of Git - http://gitless.com

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit

subcommands:
  {track,untrack,status,diff,commit,branch,tag,checkout,merge,resolve,fuse,remote,publish,switch,init,history}
    track               start tracking changes to files
    untrack             stop tracking changes to files
    status              show status of the repo
...

How can I format the output to be exactly like example below. With preserved order of commands

Gitless - a version control system built on top of Git - http://gitless.com

commands:

  track               start tracking changes to files
  untrack             stop tracking changes to files
  status              show status of the repo
...

Solution

  • Subclassing argparse.RawDescriptionHelpFormatter was too much work, so I've used this hack to extract command list and build my own message.

    def print_help(parser):
      """print help for humans"""
      print(parser.description)
      print('\ncommands:\n')
    
      # https://stackoverflow.com/questions/20094215/argparse-subparser-monolithic-help-output
      # retrieve subparsers from parser
      subparsers_actions = [
          action for action in parser._actions 
          if isinstance(action, argparse._SubParsersAction)]
      # there will probably only be one subparser_action,
      # but better save than sorry
      for subparsers_action in subparsers_actions:
          # get all subparsers and print help
          for choice in subparsers_action._choices_actions:
              print('    {:<19} {}'.format(choice.dest, choice.help))