Extend argparse to write set names in the help text for optional argument choices and define those sets once at the end

Posted by Kent on Stack Overflow See other posts from Stack Overflow or by Kent
Published on 2012-03-14T12:57:12Z Indexed on 2012/03/23 23:29 UTC
Read the original article Hit count: 200

Filed under:
|

Example of the problem

If I have a list of valid option strings which is shared between several arguments, the list is written in multiple places in the help string. Making it harder to read:

def main():
    elements = ['a', 'b', 'c', 'd', 'e', 'f']

    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-i',
        nargs='*',
        choices=elements,
        default=elements,
        help='Space separated list of case sensitive element names.')
    parser.add_argument(
        '-e',
        nargs='*',
        choices=elements,
        default=[],
        help='Space separated list of case sensitive element names to '
        'exclude from processing')

    parser.parse_args()

When running the above function with the command line argument --help it shows:

usage: arguments.py [-h] [-i [{a,b,c,d,e,f} [{a,b,c,d,e,f} ...]]]
                    [-e [{a,b,c,d,e,f} [{a,b,c,d,e,f} ...]]]

optional arguments:
  -h, --help            show this help message and exit
  -i [{a,b,c,d,e,f} [{a,b,c,d,e,f} ...]]
                        Space separated list of case sensitive element names.
  -e [{a,b,c,d,e,f} [{a,b,c,d,e,f} ...]]
                        Space separated list of case sensitive element names
                        to exclude from processing

What would be nice

It would be nice if one could define an option list name, and in the help output write the option list name in multiple places and define it last of all. In theory it would work like this:

def main_optionlist():
    elements = ['a', 'b', 'c', 'd', 'e', 'f']

    # Two instances of OptionList are equal if and only if they
    # have the same name (ALFA in this case)

    ol = OptionList('ALFA', elements)

    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-i',
        nargs='*',
        choices=ol,
        default=ol,
        help='Space separated list of case sensitive element names.')
    parser.add_argument(
        '-e',
        nargs='*',
        choices=ol,
        default=[],
        help='Space separated list of case sensitive element names to '
        'exclude from processing')

    parser.parse_args()

And when running the above function with the command line argument --help it would show something similar to:

usage: arguments.py [-h] [-i [ALFA [ALFA ...]]]
                    [-e [ALFA [ALFA ...]]]

optional arguments:
  -h, --help            show this help message and exit
  -i [ALFA [ALFA ...]]
                        Space separated list of case sensitive element names.
  -e [ALFA [ALFA ...]]
                        Space separated list of case sensitive element names
                        to exclude from processing
sets in optional arguments:
  ALFA                  {a,b,c,d,e,f}

Question

I need to:

  • Replace the {'l', 'i', 's', 't', 's'} shown with the option name, in the optional arguments.
  • At the end of the help text show a section explaining which elements each option name consists of.

So I ask:

  1. Is this possible using argparse?
  2. Which classes would I have to inherit from and which methods would I need to override?

I have tried looking at the source for argparse, but as this modification feels pretty advanced I don´t know how to get going.

© Stack Overflow or respective owner

Related posts about python

Related posts about argparse