0

I have a python script that I want to use as a wrapper for another commandline tool. I want to intercept any subcommands that I have defined, but pass through all other subcommands and arguments. I have tried using a subparser, which seems ideal, but it doesn't seem to allow accepting a generic undefined command, something similar to what parse_known_args does for a regular ArgumentParser.

What I currently have:

ap = argparse.ArgumentParser()
subparsers = ap.add_subparsers(
    title="My Subparser",
)
upload_parser = subparsers.add_parser('upload', help='upload help')
upload_parser.add_argument(
    'path',
    help="Path to file for upload"
)
upload_parser.add_argument(
    '--recursive',
    '-r',
    action='store_true',
)

What I would like to add:

generic_parser = subparser.add_parser('*', help='generic help') # "*" to indicate any other value
generic_parser.add_argument(
    'args',
    nargs='*',
    help='generic command arguments for passthru'
)

This does not work, as it simply expects either upload or a literal asterisk *.

More precisely, I want there to be a subcommand, I just don't know before hand what all the subcommands will be (or really I don't want to list out every subcommand of the tool I'm trying to wrap).


Upon further thought I have realized that this approach is somewhat flawed for my use in a few ways, though I think that this functionality might have its uses elsewhere, so I will leave the question up.

For my case, there is a conflict between seeing the help for my tool versus the one it wraps. That is, I can't distinguish between when the user wants to see the help for the wrapper or see the help for the tool it wraps.

Joseph Glover
  • 330
  • 3
  • 11
  • Try argparse remainder : https://docs.python.org/3/library/argparse.html#argparse-remainder – pyOliv May 20 '20 at 04:17
  • Unfortunately it's not an issue with how to slurp the rest of arguments, it's that the subparser complains if a subparser command wasn't given. That is, in my example only `myprog upload` or `myprog *` are acceptable, where as I want `myprog anything` to be acceptable. – Joseph Glover May 20 '20 at 04:25
  • In a way I would like an optional subparser, but more precisely I want there to be a subcommand, I just don't know before hand what all the subcommands will be (or really I don't want to list out every subcommand of the tool I'm trying to wrap). – Joseph Glover May 20 '20 at 04:26
  • `argparse` is designed to raise an error when given inputs that it does not recognize. And to give the user specific help about usage. If you don't need/want that kind of help or control, don't use `argparse`. Slurp up `sys.argv` and process it in what ever exotic way you want. – hpaulj May 20 '20 at 06:56

1 Answers1

0

I think you can try Click, this is really powerful and easy to use!

just check this example

import click

@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
              help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo('Hello %s!' % name)

if __name__ == '__main__':
    hello()
imanux
  • 11
  • 2