Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Argparse with ArgumentDefaultsHelpFormatter and RawTextHelpFormatter

I'm using argparse with Python 2.7 I would like to use RawTextHelpFormatter to get line feeds in the epilog and ArgumentDefaultsHelpFormatter to get the defaults displayed in the default help.

For example, if the epilog part of ArgumentParser is:

 epilog="first line\n second line"

and there are arguments:

group.add_argument(
    "-d",
    "--development",
    action="store_true",
    dest="build_dev",
    default="False",
    help="Build development code",
)
group.add_argument(
    "-p",
    "--production",
    action="store_true",
    dest="build_prod",
    default="False",
    help="Build production release",
)

The help output should be:

   -d, --development   Build development code (default: False)
   -p, --production    Build production release (default: False)
first line
second line

Is there a way to do that?

like image 443
Alan Avatar asked Sep 01 '25 10:09

Alan


2 Answers

Inserting your own default in the help works but is not ideal. This is because it is an unnecessary maintenance burden for the following reasons:

  • every new argument will need that text added

  • all that repetition clutters the code obscuring the details that matter

  • future design changes such as no longer showing the defaults would require deleting that text from every argument

  • advanced features such as making whether to show the defaults a user configurable option would be excluded by the hard-coding of the default text

Therefore, it is much better to take advantage of python's multiple inheritance to make a new formatter with the functionality of all the relevant supplied formatters, in this case RawTextHelpFormatter and ArgumentDefaultsHelpFormatter, e.g. like this:

import argparse


class UltimateHelpFormatter(
    argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter
):
    pass


group = argparse.ArgumentParser(
    epilog="first line\n second line",
    formatter_class=UltimateHelpFormatter,
)
group.add_argument(
    "-d",
    "--development",
    action="store_true",
    dest="build_dev",
    default="False",
    help="Build development code",
)
group.add_argument(
    "-p",
    "--production",
    action="store_true",
    dest="build_prod",
    default="False",
    help="Build production release",
)
group.print_help()

The above gives this output:

usage: prog.py [-h] [-d] [-p]

optional arguments:
  -h, --help         show this help message and exit
  -d, --development  Build development code (default: False)
  -p, --production   Build production release (default: False)

first line
 second line
like image 98
Biggsy Avatar answered Sep 02 '25 23:09

Biggsy


Inserting your own default in the help:

In [324]: parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, 
     ...:    epilog="first line\n second line") 
     ...: group = parser.add_argument_group('test') 
     ...: group.add_argument( 
     ...:     "-d", 
     ...:     "--development", 
     ...:     action="store_true", 
     ...:     dest="build_dev", 
     ...:     default="False", 
     ...:     help="Build development code (default: %(default)s)", 
     ...:  ) 
     ...: group.add_argument( 
     ...:     "-p", 
     ...:     "--production", 
     ...:     action="store_true", 
     ...:     dest="build_prod", 
     ...:     default="False", 
     ...:     help="Build production release (default: %(default)s", 
     ...:  )                                                                                           
Out[324]: _StoreTrueAction(option_strings=['-p', '--production'], dest='build_prod', nargs=0, const=True, default='False', type=None, choices=None, help='Build production release (default: %(default)s', metavar=None)
In [325]: parser.print_help()                                                                          
usage: ipython3 [-h] [-d] [-p]

optional arguments:
  -h, --help         show this help message and exit

test:
  -d, --development  Build development code (default: False)
  -p, --production   Build production release (default: False

first line
 second line
like image 45
hpaulj Avatar answered Sep 02 '25 23:09

hpaulj