Title: argparse: customizable help formatter
Type: enhancement Stage: patch review
Components: Library (Lib) Versions: Python 3.10
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: monkeyman79, paul.j3, rhettinger
Priority: normal Keywords: patch

Created on 2021-01-19 14:27 by monkeyman79, last changed 2021-01-29 21:27 by monkeyman79.

File name Uploaded Description Edit
CustomizableHelpFormatter.txt monkeyman79, 2021-01-19 14:26
Pull Requests
URL Status Linked Edit
PR 24377 open monkeyman79, 2021-01-29 19:47
Messages (3)
msg385263 - (view) Author: Tadek Kijkowski (monkeyman79) * Date: 2021-01-19 14:26
Current implementation of the argparse module doesn't make it easy for developers to customize the help text message format. On one hand the module doesn't provide any builtin ways to do it, and the only way is to provide developer's own formatter class, on the other hand developers are threatened, that all internal structures of the module, including API of the HelpFormatter class is subject to change. Trying to customize anything but the most basic things, developer risks that his or hers module will suddenly stop working with a new version of argparse.

For most basic customization there is a set of four alternative formatting classes, but their usage as well as development of additional formatting classes is hindered by following reasons:
- Only one formatting class can be used at a time. Although arguably devloper can safely derive his own formatter class from multiple argparse's formatters - if he or she will come up with this idea.
- At this moment there is no way to pass any configuration data to the formatter object, so each formatter class can only change one aspect of the output format.
- Any new functionality added to argparse help formatting has to take form of new formatter class. If it is significant change, it means duplicating parts of HelpFormatter code and in the future maintaining additional classes.
- Even if additional formatter classes are added to argparse, developers have make sure that the new class is present in the argparse used by their module - either add dependency to specific argparse version, or dynamically check for presence of the new class in argparse module.

The most important part of this enhancement request is change in argparse public API - addition of class CustomHelpFormat. Object of this class would serve as factory for CustomizableHelpFormatter objects and could be passed to ArgumentParser constructor in place of format class type:

custom_format = argparse.CustomHelpFormat()
custom_format.indent_increment = 4
custom_format.raw_description = True
parser = argparse.ArgumentParser(formatter_class=custom_format)

The idea of passing callable instead of class type as formatter_class argument is not new, but this time it would be part of official API with access to internal details and maintained along with the module.

In conrtast to the list of drawbacks above, the advantages of this solution are:
- It is much easier to do basic customization. Developers won't have to search the internet for information how to customize argparse output, when they just want to focus on their own application functionality.
- There is no need to check for presence of future additional help formatter in the argparse module. One just has to set appropriate attribute in the 'custom_format' object. If required functionality is not present in the module on the system, it would be simply ignored, developer could even safely set attribute for future feature not present in released version.
- Detection of implemented feature would is much easier - developer would just call `hasattr(custom_format, "hybrid_text_formatter")` and modify displayed text accordingly in the absence of the requested feature.
- Development of new features should be easier - instead of creating new class for each possible aspect of customization, new features could be combined in one new class, or even added to the base HelpFormatter and just enabled by an attribute.

Altough this solution will not immediately help developers wanting to customize their argparse, the main idea is that it will unclog development of new formatters and incorporating existing propositions and possibly lessen or remove the need for client side customizations.

Initially, the new class would contain attributes corresponding to funcionality of existing alternative formatting classes as well as arguments to default HelpFormatter - indent, max help position and width.

Attached implementation of the CustomizableHelpFormatter class may seem rudimentary or hackish (or maybe not). Perhaps it should implement all appropriate methods instead of patching self.
msg385509 - (view) Author: paul j3 (paul.j3) * (Python triager) Date: 2021-01-22 19:42
Years ago I proposed a `format_wrapper`, a Format class factory


There I show that the formatter may be lambda

    formatter = lambda prog: argparse.HelpFormatter(prog, width=100)

The need for improving help customization has been around for a long time:
Improve argparse usage/help customization
Make the API of argparse.HelpFormatter public
msg385942 - (view) Author: Tadek Kijkowski (monkeyman79) * Date: 2021-01-29 21:27
This is just repackaging old ideas into nice box. Instead of creating lambdas or generator function for each particular case, there is one easy to use, universal class. It will be finally written in official documentation how to change indentation.
Date User Action Args
2021-01-29 21:27:53monkeyman79setmessages: + msg385942
2021-01-29 19:47:25monkeyman79setkeywords: + patch
stage: patch review
pull_requests: + pull_request23197
2021-01-22 19:42:38paul.j3setmessages: + msg385509
2021-01-21 16:38:06shihai1991setnosy: + rhettinger, paul.j3
2021-01-19 14:29:43monkeyman79settitle: argpare: customizable help formatter -> argparse: customizable help formatter
2021-01-19 14:27:00monkeyman79create