I'm trying to create a command line tool (let's call it 'X') that wraps another tool (let's call it 'Y').
I handle some cases specially, and add some options of myself, but I want to redirect whatever I don't want to handle to the tool Y.
So far I managed to redirect the arguments that don't come with dashes, for example X Y option1 option2 option3
will just call Y option1 option2 option3
. I did this by adding a subparser Y
and an argument any
to it
Here's the code (x.py):
main_parser = argparse.ArgumentParser()
subparsers = main_parser.add_subparsers(dest="parser_name")
y_subparser = subparsers.add_parser('y')
y_options = y_subparser.add_argument('any', nargs='*')
Then in my handler code, i do this:
args = main_parser.parse_args()
if args.parser_name == 'y':
command_string = ' '.join(['y'] + sys.argv[2:])
os.system(command_string)
When I call python x.py y asdf zxcv qwer
it works.
When I call python x.py y asdf zxcv qwer -option
I get the error x.py: error: unrecognized arguments: -option
I realize that if stuff just gets too complicated with argparse i can always fall back to using sys.argv
, but if you know this to be doable, please share.
I've also been looking through the argparse code, which is a little dense, and where it seems that ArgumentParser._parse_known_args
does everything (300 lines). But before I go deeper, I thought maybe someone knows how to do this - if not, i'll post my discoveries here if someone else has the same problem.
After importing the library, argparse. ArgumentParser() initializes the parser so that you can start to add custom arguments. To add your arguments, use parser. add_argument() .
Python argparse optional argument The example adds one argument having two options: a short -o and a long --ouput . These are optional arguments. The module is imported. An argument is added with add_argument .
The store_true option automatically creates a default value of False. Likewise, store_false will default to True when the command-line argument is not present. The source for this behavior is succinct and clear: http://hg.python.org/cpython/file/2.7/Lib/argparse.py#l861.
From the doc of argparse, you can use argparse.REMAINDER
:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo')
>>> parser.add_argument('command')
>>> parser.add_argument('args', nargs=argparse.REMAINDER)
>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
This work even with dashed in the subcommand arguments
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo')
>>> parser.add_argument('command')
>>> parser.add_argument('args', nargs=argparse.REMAINDER)
>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ --foobar'.split()))
Namespace(args=['--arg1', 'XX', 'ZZ', '--foobar'], command='cmd', foo='B')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With