Reputation: 883
Given sth. like (or similar to):
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("FILES", nargs="+", type=str)
args = parser.parse_args()
Now I'd like to have the many-valued positional argument FILES
displayed in the usage message as
usage: cli.py [-h] FILES
instead of
usage: cli.py [-h] FILES [FILES ...]
Any step-by-step explanations or pointers are appreciated.
Upvotes: 2
Views: 548
Reputation: 2624
fbahr, I just decided to dive into the source code of argparse. I found out the formatting of the usage is hardcoded, look at it here. The only way you can override it is inheriting from HelpFormatter (the default class used when creating a new ArgumentParser instance) and say to the parser to use the class you created, to use your own formatter. You will have to override a "private" method (it is prefixed with an underscore) named _format_args, which is a little ugly and anti-pattern (in fact the only reason you can do that is because we are using Python) but it seems to be the only way to customize argparse the way you wanna do it.
import argparse
class NArgsCustomUsageHelpFormatter(argparse.HelpFormatter):
def _format_args(self, action, default_metavar):
get_metavar = self._metavar_formatter(action, default_metavar)
if action.nargs == argparse.ONE_OR_MORE:
result = '%s' % get_metavar(1)
else:
result = argparse.HelpFormatter._format_args(self, action, default_metavar)
return result
parser = argparse.ArgumentParser(formatter_class=NArgsCustomUsageHelpFormatter)
parser.add_argument("FILES", nargs="+", type=str)
args = parser.parse_args()
The code above just change the default behaviour if the action to be formatted needs at least one argument (nargs='+'
), otherwise it doesn't do anything different.
I hope this help you!
Upvotes: 1
Reputation: 473873
This is the built-in behavior of the default formatter: source.
You could have your custom formatter with special handling for the nargs="+"
type arguments:
import argparse
class CustomFormatter(argparse.HelpFormatter):
def _format_args(self, action, default_metavar):
get_metavar = self._metavar_formatter(action, default_metavar)
if action.nargs == argparse.ONE_OR_MORE:
return '%s' % get_metavar(1)
else:
return super(CustomFormatter, self)._format_args(action, default_metavar)
parser = argparse.ArgumentParser(formatter_class=CustomFormatter)
parser.add_argument("FILES", nargs="+", type=str)
args = parser.parse_args()
Would print out:
usage: cli.py [-h] FILES
cli.py: error: the following arguments are required: FILES
Upvotes: 4