views:

659

answers:

4

Using python's optparse module I would like to add extra example lines below the regular usage output. My current help_print() output looks like this:

usage: check_dell.py [options]

options:
-h, --help     show this help message and exit
-s, --storage  checks virtual and physical disks
-c, --chassis  checks specified chassis components

I would like it to include usage examples for the less *nix literate users at my work. Something like this:

usage: check_dell.py [options]

options:
-h, --help     show this help message and exit
-s, --storage  checks virtual and physical disks
-c, --chassis  checks specified chassis components

Examples:

check_dell -c all
check_dell -c fans memory voltage
check_dell -s

How would I accomplish this? What optparse options allow for such? Current code:

import optparse

def main():
    parser = optparse.OptionParser()
    parser.add_option('-s', '--storage', action='store_true', default=False, help='checks virtual and physical disks')
    parser.add_option('-c', '--chassis', action='store_true', default=False, help='checks specified chassis components')

(opts, args) = parser.parse_args()
+2  A: 

Use the usage parameter:

usage = "usage: %prog [options] arg1 arg2"
parser = OptionParser(usage=usage)

You can add more through (just an example):

group = OptionGroup(parser, "Dangerous Options",
                    "Caution: use these options at your own risk.  "
                    "It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)

Example output:

usage: [options] arg1 arg2

options: -h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-fFILE, --file=FILE write output to FILE
-mMODE, --mode=MODE interaction mode: one of 'novice', 'intermediate', [default], 'expert'

Dangerous Options: Caution: use of these options is at your own risk. It is believed that some of them bite. -g Group option.

Have a look here.

jldupont
Thanks for the quick help! What if I wanted the examples to appear below the regular usage summary?
CarpeNoctem
Trying OptionGroup now, thanks!
CarpeNoctem
A: 

There is a description parameter you can pass to the OptionParser constructor. This allows you to include arbitrary text that appars after usage, but before the list of options.

See 16.4.3.1. Creating the parser.

Yang Zhao
+10  A: 
parser = optparse.OptionParser(epilog="otherstuff")

The default format_epilog strips the newlines (uses textwrap), so you would need to override format_epilog in your parser like this.

def main():

    class MyParser(optparse.OptionParser):
        def format_epilog(self, formatter):
            return self.epilog

    parser =MyParser(epilog=
"""Examples:

check_dell -c all
check_dell -c fans memory voltage
check_dell -s
""")
...

Here's a bit more detail.
If you look in optparse.py in the class OptionParser there is a method called format_epilog which is called by format_help

here is the snippet from optparse.py

def format_epilog(self, formatter):
    return formatter.format_epilog(self.epilog)

def format_help(self, formatter=None):
    if formatter is None:
        formatter = self.formatter
    result = []
    if self.usage:
        result.append(self.get_usage() + "\n")
    if self.description:
        result.append(self.format_description(formatter) + "\n")
    result.append(self.format_option_help(formatter))
    result.append(self.format_epilog(formatter))
    return "".join(result)

The default behaviour of formatter.format_epilog is to use textwrap.fill which amongst other things, strips the newlines from the epilog. Since we want the newlines to be preserved, we subclass OptionParser and change the behaviour of format_epilog

gnibbler
Thank you very much, that's awesome, since it's not documented on the optparse page.
Tordek
This will be my first non-bash script so please excuse my n00bness. What if I wanted three or four lines of epilog?
CarpeNoctem
Just 3 extra lines, I've edited my answer
gnibbler
+1 - you learn something new everyday. I knew about `description` and have used it for similar purposes. This is much nicer. Interestingly enough, it is mentioned in the _in interpreter help_ so it is in the docstring... `import optparse; help(optparse.OptionParser)` shows it...
D.Shawley
I added it and it works great! Thanks gnibbler. I read the Chapter on OOP in "Core Python" just yesterday, and I haven't the slightest what is going on here. I am going to stare blankly at it for the next few hours till I get it. Wish me luck.
CarpeNoctem
Ok, I've tried to add some more explanation for you.
gnibbler
+10 if I could.
Dennis Williamson
epilog appears to have been added after 2.4 :(
CarpeNoctem
A: 

Another idea on how to do this would be disabling the default behavior for -h and printing your own help screen, which can include the default one:

from optparse import OptionParser

parser = OptionParser(add_help_option=False, epilog='This can't be easily \n multilined')
parser.add_option('-h', '--help', dest='help', action='store_true', help='show this help message and exit')

(option, arg) = parser.parse_args(sys.argv)
if option.help:
    parser.print_help()
    print 'now we have an epilog'
    print 'with as many lines as you wish'
    sys.exit()

That is basically what the parser does with the default behavior of add_help_option=True, excluding of course the prints.

But, in all honesty, I'd also prefer a way to simply add any given number of description lines in the beginning and in the end.

Cawas