Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I format positional argument help using Python's optparse?

As mentioned in the docs the optparse.OptionParser uses an IndentedHelpFormatter to output the formatted option help, for which which I found some API documentation.

I want to display a similarly formatted help text for the required, positional arguments in the usage text. Is there an adapter or a simple usage pattern that can be used for similar positional argument formatting?

Clarification

Preferably only using the stdlib. Optparse does great except for this one formatting nuance, which I feel like we should be able to fix without importing whole other packages. :-)

like image 367
cdleary Avatar asked Mar 13 '09 13:03

cdleary


People also ask

What is positional argument in Python?

A positional argument in Python is an argument whose position matters in a function call. You have likely used positional arguments without noticing. For instance: def info(name, age): print(f"Hi, my name is {name}.

How do you pass arguments to a Python script?

In Python, arguments are passed to a script from the command line using the sys package. The argv member of sys ( sys. argv ) will store all the information in the command line entry and can be accessed inside the Python script. Python's getopt module can also be used to parse named arguments.


3 Answers

The best bet would be to write a patch to the optparse module. In the meantime, you can accomplish this with a slightly modified OptionParser class. This isn't perfect, but it'll get what you want done.

#!/usr/bin/env python from optparse import OptionParser, Option, IndentedHelpFormatter  class PosOptionParser(OptionParser):     def format_help(self, formatter=None):         class Positional(object):             def __init__(self, args):                 self.option_groups = []                 self.option_list = args          positional = Positional(self.positional)         formatter = IndentedHelpFormatter()         formatter.store_option_strings(positional)         output = ['\n', formatter.format_heading("Positional Arguments")]         formatter.indent()         pos_help = [formatter.format_option(opt) for opt in self.positional]         pos_help = [line.replace('--','') for line in pos_help]         output += pos_help         return OptionParser.format_help(self, formatter) + ''.join(output)      def add_positional_argument(self, option):         try:             args = self.positional         except AttributeError:             args = []         args.append(option)         self.positional = args      def set_out(self, out):         self.out = out def main():     usage = "usage: %prog [options] bar baz"     parser = PosOptionParser(usage)     parser.add_option('-f', '--foo', dest='foo',                       help='Enable foo')     parser.add_positional_argument(Option('--bar', action='store_true',                                    help='The bar positional argument'))     parser.add_positional_argument(Option('--baz', action='store_true',                                    help='The baz positional argument'))     (options, args) = parser.parse_args()     if len(args) != 2:         parser.error("incorrect number of arguments")     pass  if __name__ == '__main__':     main() 

And the output you get from running this:

Usage: test.py [options] bar baz    Options:     -h, --help         show this help message and exit     -f FOO, --foo=FOO  Enable foo  Positional Arguments:   bar  The bar positional argument   baz  The baz positional argument 
like image 162
Douglas Mayle Avatar answered Sep 23 '22 02:09

Douglas Mayle


Try taking a look at argparse. Documentation says it supports position arguments and nicer looking help messages.

like image 28
Richard Levasseur Avatar answered Sep 25 '22 02:09

Richard Levasseur


I'd be interested in a clean solution to this; I wasn't able to come up with one. The OptionParser really focuses entirely on the options; it doesn't give you anything to work with position args, as far as I've been able to find.

What I did was to generate a list of little documentation blocks for each of my positional arguments, using \ts to get the right spacing. Then I joined them with newlines, and appended that to the 'usage' string that gets passed to the OptionParser.

It looks fine, but it feels silly, and of course that documentation ends up appearing above the list of options. I haven't found any way around that, or how to do any complex stuff, i.e. a given set of options is described beneath the description for a positional arg, because they only apply to that arg.

I looked at monkey-patching OptionParser's methods and I remember (this was a year or so ago) that it wouldn't have been that difficult, but I didn't want to go down that path.

like image 45
DNS Avatar answered Sep 24 '22 02:09

DNS