classification
Title: Argparse does not propagate HelpFormatter class to subparsers
Type: behavior Stage: resolved
Components: Extension Modules Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Michael.Cohen, iritkatriel, paul.j3
Priority: normal Keywords:

Created on 2014-06-01 23:32 by Michael.Cohen, last changed 2021-05-27 20:59 by iritkatriel. This issue is now closed.

Messages (3)
msg219534 - (view) Author: Michael Cohen (Michael.Cohen) Date: 2014-06-01 23:32
Argparse has an option to set the custom help formatter class as a kwarg. For example one can define:


class MyHelpFormatter(argparse.RawDescriptionHelpFormatter):
    def add_argument(self, action):
        if action.dest != "SUPPRESS":
            super(RekallHelpFormatter, self).add_argument(action)


parser = ArguementParser(
   formatter_class=MyHelpFormatter)


But when one creates a subparser there is no way to define the formatter class for it - i.e. parser.add_subparsers() does not accept a formatter_class parameter. Instead we see this code:

    def add_subparsers(self, **kwargs):
        ...
        # add the parser class to the arguments if it's not present
        kwargs.setdefault('parser_class', type(self))

The only way to make this work is to extend ArguementParser to force it to use the formatter_class through inheritance:

class MyArgParser(argparse.ArgumentParser):

    def __init__(self, **kwargs):
        kwargs["formatter_class"] = MyHelpFormatter
	super(MyArgParser, self).__init__(**kwargs)

this is counter intuitive since formatter_class can be passed to the constructor but then it is not propagated to subparsers.

IMHO the expect action here is to have the formatter_class automatically propagates to subparsers as well. Short of that we need to be able to specific it in add_subparser() call.
msg219648 - (view) Author: paul j3 (paul.j3) * (Python triager) Date: 2014-06-02 22:35
You can specify the 'formatter_class' when creating each subparser:

    sp1=sp.add_parser('cmd1', formatter_class = argparse.RawDescriptionHelpFormatter)

The 'add_parser' command is the one that passes a variety of **kwargs to 'ArgumentParser' (or what ever parser creator is being used for the subparsers).  'add_subparsers' is more like a 'add_argument' command, creating a '_SubParsersAction' instance.

Few, if any, attributes of the main parser are propagated to the subparsers.  I'd have to study the code more closely, but I think it's just the parser class that is propagated.
msg394602 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-05-27 20:59
What Paul explained is also covered in the documentation here: https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_subparsers
History
Date User Action Args
2021-05-27 20:59:29iritkatrielsetstatus: open -> closed

nosy: + iritkatriel
messages: + msg394602

resolution: not a bug
stage: resolved
2014-06-02 22:35:56paul.j3setnosy: + paul.j3
messages: + msg219648
2014-06-01 23:32:36Michael.Cohencreate