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.

Asked By: Spycho

||

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.

Answered By: Spycho

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.

Answered By: hpaulj
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.