Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I avoid the capital placeholders in python's argparse module?

There was a question that asked where they come from, and the accepted answer was a bunch of links to tutorials and source code. Explanation for argparse python modul behaviour: Where do the capital placeholders come from?

None of it was helpful to me, I want to either get rid of them, or know their purpose.

For example, a line like this:

parser.add_argument('-c', '--chunksize', type=int, help='chunk size in bits')

produces garbage like this:

optional arguments:
  -h, --help            show this help message and exit
  -c CHUNKSIZE, --chunksize CHUNKSIZE
                        chunk size in bits

and if I try with an empty metavar string:

parser.add_argument('-c', '--chunksize', metavar='', type=int, help='chunk size in bits')

I get a space after the comma:

optional arguments:
  -h, --help            show this help message and exit
  -c , --chunksize      chunk size in bits
like image 689
bug Avatar asked Jun 06 '13 17:06

bug


People also ask

How do you make an argument optional in Argparse?

Optional Arguments To add an optional argument, simply omit the required parameter in add_argument() . args = parser.

What does Nargs do in Argparse?

By default, argparse will look for a single argument, shown above in the filename example. If you want your parameters to accept a list of items you can specify nargs=n for how many arguments to accept. Note, if you set nargs=1 , it will return as a list not a single value.

What is Store_true in Python?

The store_true option automatically creates a default value of False. Likewise, store_false will default to True when the command-line argument is not present. The source for this behavior is succinct and clear: http://hg.python.org/cpython/file/2.7/Lib/argparse.py#l861.


2 Answers

parser.add_argument('-c', '--chunksize', metavar='\b', type=int, help='chunk size in bits')

seems to work

like image 95
Aravind Avatar answered Sep 23 '22 23:09

Aravind


You can make your formatter class to format the arguments whichever way you want. It's not entirely straight forward, but here's one that produces the following output (assuming @mgilson is correct in the assumption that you wanted to only display the metavar once for the set of command names... Otherwise just specify an actual metavar='value' and it will display precisely that text.):

# without metavar specified:
-c, --chunksize CHUNKSIZE
                chunk size in bits
# with metavar specified:
-c, --chunksize some_metavar
                chunk size in bits

And the code for the class and reproducing the two outputs:

import argparse
# 2.7-3.2
class SingleMetavarHelpFormatter(argparse.HelpFormatter):
    def _format_action_invocation(self, action):
        if not action.option_strings:
            metavar, = self._metavar_formatter(action, action.dest)(1)
            return metavar

        else:
            parts = []

            # if the Optional doesn't take a value, format is:
            #    -s, --long
            if action.nargs == 0:
                parts.extend(action.option_strings)

            # if the Optional takes a value, format is:
            #    -s ARGS, --long ARGS
            else:
                default = action.dest.upper()
                args_string = self._format_args(action, default)

                ## THIS IS THE PART REPLACED
                #~ for option_string in action.option_strings:
                    #~ parts.append('%s %s' % (option_string, args_string)) ### this is change
                ## /SECTION REPLACED

                ## NEW CODE:
                parts.extend(action.option_strings)
                parts[-1] += ' %s' % args_string
                ## /NEW CODE
            return ', '.join(parts)


parser = argparse.ArgumentParser(
    prog='PROG',
    formatter_class=SingleMetavarHelpFormatter
    )

parser.add_argument('-c', '--chunksize', type=int, help='no metavar specified')
parser.add_argument('-w', '--with_metavar', type=int, help='metavar specified', metavar='some_metavar')

parser.print_help()

edit: To not show a metavar at all, you can pass an empty string to metavar:

parser.add_argument('-e', '--with_empty_metavar', type=int, help='empty metavar specified', metavar='')

The difference between doing that with the original class and the new class is the lack extra space character after the short command syntax.

#usage: PROG [-h] [-c CHUNKSIZE] [-w some_metavar] [-e]
#
#optional arguments:
#  -h, --help            show this help message and exit
#  -c CHUNKSIZE, --chunksize CHUNKSIZE
#                        no metavar specified
#  -w some_metavar, --with_metavar some_metavar
#                        metavar specified
#  -e, --with_empty_metavar
#                        empty metavar specified
like image 33
Nisan.H Avatar answered Sep 22 '22 23:09

Nisan.H