Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python argparse - Grouping parent parser arguments into groups

Is there a way to group the arguments from parent parsers into different groups? I don't have access to the parent parser itself, so I can't add the group there. (I'm using Google's OAuth2 framework).

Currently my code is:

# test.py
from argparse import ArgumentParser
from oauth2client import tools

parser = ArgumentParser(description="My program", parents=[tools.argparser])
parser.add_argument("--foo", help="Foo the data")
parser.add_argument("--bar", help="Bar the data")

parser.parse_args()

Which produces the following help:

$ python test.py -h                                    
usage: test.py [-h] [--auth_host_name AUTH_HOST_NAME]
               [--noauth_local_webserver]
               [--auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT ...]]]
               [--logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
               [--foo FOO] [--bar BAR]

My program

optional arguments:
  -h, --help            show this help message and exit
  --auth_host_name AUTH_HOST_NAME
                        Hostname when running a local web server.
  --noauth_local_webserver
                        Do not run a local web server.
  --auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT ...]]
                        Port web server should listen on.
  --logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
                        Set the logging level of detail.
  --foo FOO             Foo the data
  --bar BAR             Bar the data

So, I would like to create a group for arguments from the parent parser. Is is possible to group the arguments to look something like this?

optional arguments:
  -h, --help            show this help message and exit
  --foo FOO             Foo the data
  --bar BAR             Bar the data

authentication options:
  --auth_host_name AUTH_HOST_NAME
                        Hostname when running a local web server.
  --noauth_local_webserver
                        Do not run a local web server.
  --auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT ...]]
                        Port web server should listen on.
  --logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
                        Set the logging level of detail.

I know about parser groups, but I need to somehow get the arguments from one place to another something like:

auth_group = parser.add_argument_group('authentication options')
for arg in get_args_from_parser(tools.argparser):
    auth_group.add_argument(arg)

But I can't find a way to list arguments like that or copy them from one place to another.

like image 340
dtauxe Avatar asked Aug 06 '26 23:08

dtauxe


1 Answers

Thanks to @hpaulj and the question "Reorder Python argparse argument groups"

The way to do this depends on the implementation details of argparse, as I probably should have expected, so use at your own risk. But this works with the current Python 3.7.0.

We can rename the group(s) in the parent parser before adding it to my own:

# test.py
from argparse import ArgumentParser
from oauth2client import tools

tools.argparser._action_groups[1].title = 'authentication options'

parser = ArgumentParser(description="My program", parents=[tools.argparser])
parser.add_argument("--foo", help="Foo the data")
parser.add_argument("--bar", help="Bar the data")

parser.parse_args()

Which results in the output:

$ python test.py -h                                    
usage: test.py [-h] [--auth_host_name AUTH_HOST_NAME]
               [--noauth_local_webserver]
               [--auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT ...]]]
               [--logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
               [--foo FOO] [--bar BAR]

My program

optional arguments:
  -h, --help            show this help message and exit
  --foo FOO             Foo the data
  --bar BAR             Bar the data

authentication options:
  --auth_host_name AUTH_HOST_NAME
                        Hostname when running a local web server.
  --noauth_local_webserver
                        Do not run a local web server.
  --auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT ...]]
                        Port web server should listen on.
  --logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}
                        Set the logging level of detail.

This works by renaming one of the default groups in the parent parser. The groups are stored in parser._action_groups, and are ordered ['positional arguments', 'optional arguments'] So we are renaming the second one (which is where these arguments are) before it is added to the new parser. This also stops the groups from being merged.

like image 167
dtauxe Avatar answered Aug 08 '26 11:08

dtauxe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!