When using argparse, passing --help
to the program generates help text. Unfortunately, it's hard to read because there are no blank lines between options. Here's an excerpt to illustrate:
optional arguments:
-h, --help show this help message and exit
-u FILENAME, --up-sound FILENAME
The sound to play when the network comes up. Default:
"/path/to/some/sound/file.wav"
-d FILENAME, --down-sound FILENAME
The sound to play when the network goes down. Default:
"/path/to/some/other/sound/file.wav"
-p EXECUTABLE, --player EXECUTABLE
The program to use to play sounds. Default: "play"
-s, --silent If specified, network_monitor.py will not play any
sounds.
-c, --no-clear-screen
If specified, screen will not be cleared (nor extra
blank lines added) before network_monitor.py runs.
--version show program's version number and exit
Notice that in some cases, such as between -p
and -s
or between -c
and --version
, it is difficult to tell at a glance which help text applies to which option. There should be a blank line between entries. For example:
-p EXECUTABLE, --player EXECUTABLE
The program to use to play sounds. Default: "play"
-s, --silent If specified, network_monitor.py will not play any
sounds.
How can I accomplish this? Several other questions recommend using argparse.RawTextHelpFormatter
. The problem with that is that if I use it, I have to write my own logic to wrap the help text as the raw text help formatter does no formatting. The obvious answer would be to append '\n\n'
to the end of the help text and use the default formatter. But inexplicably, newlines get stripped.
What's the way forward here? I'm using Python 3.4.
Optional arguments are useful if you want to give the user a choice to enable certain features. To add an optional argument, simply omit the required parameter in add_argument() . args = parser. parse_args()if args.
poke's
approach is good. Note that RawTextHelpFormatter
also modifies this method, simplifying it to:
def _split_lines(self, text, width):
return text.splitlines()
poke's
method could be tweaked to give you more control
class BlankLinesHelpFormatter (argparse.HelpFormatter):
# add empty line if help ends with \n
def _split_lines(self, text, width):
lines = super()._split_lines(text, width)
if text.endswith('\n'):
lines += ['']
return lines
With this:
parser = argparse.ArgumentParser(description='A description',
formatter_class=BlankLinesHelpFormatter,
epilog='Epilog line',
)
parser.add_argument('-u', '--up-sound', metavar='FILENAME',
help='The sound to play when the network comes up. Default:"%(default)s"\n',
default="/path/to/some/sound/file.wav")
# note \n in above help
parser.add_argument('-d', '--down-sound', metavar='FILENAME',
help='The sound to play when the network goes down. Default:"%(default)s"',
default="/path/to/some/other/sound/file.wav")
parser.add_argument('-s','--silent', action='store_true',
help='If specified, network_monitor.py will not play any sounds.')
parser.add_argument('positional', nargs='*', help='positional argument')
parser.print_help()
displays:
usage: stack29484443.py [-h] [-u FILENAME] [-d FILENAME] [-s]
[positional [positional ...]]
A description
positional arguments:
positional positional argument
optional arguments:
-h, --help show this help message and exit
-u FILENAME, --up-sound FILENAME
The sound to play when the network comes up.
Default:"/path/to/some/sound/file.wav"
-d FILENAME, --down-sound FILENAME
The sound to play when the network goes down.
Default:"/path/to/some/other/sound/file.wav"
-s, --silent If specified, network_monitor.py will not play any
sounds.
Epilog line
For reference, the default _split_lines
is:
def _split_lines(self, text, width):
text = self._whitespace_matcher.sub(' ', text).strip()
return _textwrap.wrap(text, width)
# self._whitespace_matcher = _re.compile(r'\s+')
This removes final \n and reduces all interior whitespace to one blank.
You can create your own help text formatter that does this. Note that this requires you to be very specific to the implementation detail of the argparse.HelpFormatter
. So consider this warning that is included in every help formatter type description:
Only the name of this class is considered a public API. All the methods provided by the class are considered an implementation detail.
Once we ignore that, creating our own help formatter that adds a blank line between the entries is very simple:
class BlankLinesHelpFormatter (argparse.HelpFormatter):
def _split_lines(self, text, width):
return super()._split_lines(text, width) + ['']
And that’s it. Now when you create the ArgumentParser
object while passing
formatter_class=BlankLinesHelpFormatter
to the constructor, blank lines will appear between each argument in the help text.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With