ArgumentParser epilog and description formatting in conjunction with ArgumentDefaultsHelpFormatter
Question:
I’m using argparse to take in command line input and also to produce help text. I want to use ArgumentDefaultsHelpFormatter
as the formatter_class
, however this prevents me from also using RawDescriptionHelpFormatter
which would allow me to add custom formatting to my description or epilog.
Is there a sensible method of achieving this aside from writing code to produce text for default values myself? According to the argparse docs, all internals of ArgumentParser
are considered implementation details, not public API, so sub-classing isn’t an attractive option.
Answers:
I just tried a multiple inheritance approach, and it works:
class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter):
pass
parser = argparse.ArgumentParser(description='testntestntest.',
epilog='testntestntest.',
formatter_class=CustomFormatter)
This may break if the internals of these classes change though.
I don’t see why subclassing a HelpFormatter
should be a problem. That isn’t messing with the internals of ArgumentParser
. The documentation has examples of custom Action
and Type
classes (or functions). I take the 'there are four such classes'
line to be an invitation to write my own HelpFormatter if needed.
The provided HelpFormatter
subclasses make quite simple changes, changing just one function. So they can be easily copied or altered.
RawDescription
just changes:
def _fill_text(self, text, width, indent):
return ''.join(indent + line for line in text.splitlines(keepends=True))
In theory it could be changed without altering the API, but it’s unlikely.
The defaults formatter just changes:
def _get_help_string(self, action):
help = action.help
if '%(default)' not in action.help:
if action.default is not SUPPRESS:
defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
if action.option_strings or action.nargs in defaulting_nargs:
help += ' (default: %(default)s)'
return help
You could get the same effect by just including %(default)s
in all of your argument help lines. In contrast to the Raw
subclasses, this is just a convenience class. It doesn’t give you more control over the formatting.
I’m using argparse to take in command line input and also to produce help text. I want to use ArgumentDefaultsHelpFormatter
as the formatter_class
, however this prevents me from also using RawDescriptionHelpFormatter
which would allow me to add custom formatting to my description or epilog.
Is there a sensible method of achieving this aside from writing code to produce text for default values myself? According to the argparse docs, all internals of ArgumentParser
are considered implementation details, not public API, so sub-classing isn’t an attractive option.
I just tried a multiple inheritance approach, and it works:
class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter):
pass
parser = argparse.ArgumentParser(description='testntestntest.',
epilog='testntestntest.',
formatter_class=CustomFormatter)
This may break if the internals of these classes change though.
I don’t see why subclassing a HelpFormatter
should be a problem. That isn’t messing with the internals of ArgumentParser
. The documentation has examples of custom Action
and Type
classes (or functions). I take the 'there are four such classes'
line to be an invitation to write my own HelpFormatter if needed.
The provided HelpFormatter
subclasses make quite simple changes, changing just one function. So they can be easily copied or altered.
RawDescription
just changes:
def _fill_text(self, text, width, indent):
return ''.join(indent + line for line in text.splitlines(keepends=True))
In theory it could be changed without altering the API, but it’s unlikely.
The defaults formatter just changes:
def _get_help_string(self, action):
help = action.help
if '%(default)' not in action.help:
if action.default is not SUPPRESS:
defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
if action.option_strings or action.nargs in defaulting_nargs:
help += ' (default: %(default)s)'
return help
You could get the same effect by just including %(default)s
in all of your argument help lines. In contrast to the Raw
subclasses, this is just a convenience class. It doesn’t give you more control over the formatting.