Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make argparse parsers also function as subparsers

Say I have some parsers already defined:

foo_parser = argparse.ArgumentParser()
foo_parser.add_argument('-f')

bar_parser = argparse.ArgumentParser()
bar_parser.add_argument('-b')

Now I want those parsers to appears as sub-parsers.

parser = argparse.ArgumentParser(prog='parent')
subparsers = parser.add_subparsers()

subparsers.add_parser('foo')   # how can I associate these subparsers 
subparsers.add_parser('bar')   # with my foo and bar parsers already defined?

I know I could do this by repeating all of the add_argument calls, but I'm hoping for a DRY solution.

Does argparse allow this, or do I have to define my subparsers anew?

The reason I am asking, is that I have a collection of stand-alone scripts that I don't want to monkey with, but I would also like to provide a unified interface via sub-commands. I want to import the parsers from each of the standalone scripts, and make them behave as subparsers in the unified interface.

like image 897
Owen Avatar asked Nov 26 '25 08:11

Owen


1 Answers

Have you tried the parents mechanism? It's a way of populating a new parser (including a subparser) with arguments (and groups) from another parser. Some even use it as a way of adding a subset of arguments to multiple subparsers. It copies the arguments (Action objects) by reference. Usually that works ok, but it imposes limits on customizing the arguments.

https://docs.python.org/3/library/argparse.html#parents

==================

A subparser is created with this method:

class _SubParsersAction(Action):
    def add_parser(self, name, **kwargs):
       ....
       parser = self._parser_class(**kwargs)
       ....
       return parser

In theory it could be customized to work with your predefined parser instead of creating a new one. It probably would take me a half hour to debug such a change.

like image 98
hpaulj Avatar answered Nov 28 '25 22:11

hpaulj