Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Don't show long options twice in print_help() from argparse

I have the following code:

parser = argparse.ArgumentParser(description='Postfix Queue Administration Tool',
        prog='pqa',
        usage='%(prog)s [-h] [-v,--version]')
parser.add_argument('-l', '--list', action='store_true',
        help='Shows full overview of all queues')
parser.add_argument('-q', '--queue', action='store', metavar='<queue>', dest='queue',
        help='Show information for <queue>')
parser.add_argument('-d', '--domain', action='store', metavar='<domain>', dest='domain',
        help='Show information about a specific <domain>')
parser.add_argument('-v', '--version', action='version', version='%(prog)s 0.1')
args = parser.parse_args()

Which gives me output like this:

%./pqa                                                                                                                        
usage: pqa [-h] [-v,--version]

Postfix Queue Administration Tool

optional arguments:
  -h, --help            show this help message and exit
  -l, --list            Shows full overview of all queues
  -q <queue>, --queue <queue>
                        Show information for <queue>
  -d <domain>, --domain <domain>
                        Show information about a specific <domain>
  -v, --version         show program's version number and exit

I would very much like to know how I can 'group' commands that have two versions (ie. long options) which each also show a metavar.

This is mostly an aesthetic issue on my side, but I would still like to fix this. I have been reading manuals and texts on the internet, but either the information just isn't there or I am totally missing something here :)

like image 632
Peter van Arkel Avatar asked Aug 16 '13 13:08

Peter van Arkel


1 Answers

Putting hpaulj's answer into actual code, something like this works:

class CustomHelpFormatter(argparse.HelpFormatter):
    def _format_action_invocation(self, action):
        if not action.option_strings or action.nargs == 0:
            return super()._format_action_invocation(action)
        default = self._get_default_metavar_for_optional(action)
        args_string = self._format_args(action, default)
        return ', '.join(action.option_strings) + ' ' + args_string

fmt = lambda prog: CustomHelpFormatter(prog)
parser = argparse.ArgumentParser(formatter_class=fmt)

To additionally extend the default column size for help variables, add constructor to CustomHelpFormatter:

def __init__(self, prog):
    super().__init__(prog, max_help_position=40, width=80)

Seeing it in action:

usage: bk set [-h] [-p] [-s r] [-f] [-c] [-b c] [-t x y] [-bs s] [-bc c]
              [--crop x1 y1 x2 y2] [-g u r d l]
              monitor [path]

positional arguments:
  monitor                    monitor number
  path                       input image path

optional arguments:
  -h, --help                 show this help message and exit
  -p, --preview              previews the changes without applying them
  -s, --scale r              scales image by given factor
  -f, --fit                  fits the image within monitor work area
  -c, --cover                makes the image cover whole monitor work area
  -b, --background c         selects background color
  -t, --translate x y        places the image at given position
  -bs, --border-size s       selects border width
  -bc, --border-color c      selects border size
  --crop x1 y1 x2 y2         selects crop area
  -g, --gap, --gaps u r d l  keeps "border" around work area
like image 62
rr- Avatar answered Oct 17 '22 16:10

rr-