2

I have a program that uses argparse to process the command line. The program's command line and hence it's help becomes context sensitive. I would like to make the help reflect that context sensitivity.

e.g.

prog --mode=1 OPTA OPTB OPTC<br>
prog --mode=2 OPTD OPTE OPTF<br>

prog --mode=1 -h<br>
"In mode 1 you have four options, A,B,C,D"

prog --mode=2 -h<br>
"You mode 2 you have four options, D,E,F,G"

I should add here that this is only an example. In my actual program there could be any number of modes and they are not defined by my code, they are defined by users of my API. Therefore it is impossible to hard code the help for each mode. The actual help text is defined later.

This means altering the help strings for the argument 'option' to reflect the different modes after the --mode argument has been processed. The code, below, basically works in that the command works as expected, but the help does not.

The problem is that parse_known_args() seems to handle the -h then exit. I need parse_args() to handle the help. Obviously I could simple parse sys.argv and find --mode myself, but surely that defeats the object of argparse.

import argparse

parser = argparse.ArgumentParser(description='Test argparser')
parser.add_argument('--mode', nargs=1, type=int,
                    default=[1],
                   help='program mode')

options={
    1:["OPTA","OPTB","OPTC","OPTD"],
    2:["OPTD","OPTE","OPTF","OPTG"]}


args = parser.parse_known_args()[0]

print "Initial pass"
print args

parser.add_argument('options', type=str, nargs='+',
                    choices=options[args.mode[0]]+["ALL"],
                    default="ALL",
                   help='One or more of the options, above')

args = parser.parse_args()

print "Second pass"
print args
Eric O Lebigot
  • 81,422
  • 40
  • 198
  • 249
Jason M
  • 2,780
  • 1
  • 16
  • 23
  • should help: http://docs.python.org/dev/library/argparse.html#argumentparser-objects – Inbar Rose Nov 13 '12 at 09:21
  • 5
    It looks to me like your "mode" should be a subcommand rather than an option. – georg Nov 13 '12 at 09:23
  • 1
    I agree with @thg435. Create a two subparsers for mode 1 and mode 2 and you'll obtain exactly what you want. – Bakuriu Nov 13 '12 at 09:28
  • The example I gave is very cut down, the real code is much more complicated. In the real code it is very not 'mode' (it's --use-defs= which is combined with --module=, both are very optional) . For this reason I think 'mode' is definitely an option, it's argument is then used to import from a module and select what (optional) derived class from that module to import and override the defaults. There could be dozens of such modules and classes. The derived class is is a sort of collection, the help is an aspect of each member of that collection. – Jason M Nov 13 '12 at 10:02
  • Then I think you do not need context sensitive help. Just provide help for both. You could then add an argument to the "help" option so that the user can get context specific and detailed information on each mode. – Bakuriu Nov 13 '12 at 11:02
  • Bakuriu: As I said above, there could by any number of 'modes'. It would not make sense to redistribute the package with a new help system each time a user create a new derived class. Their class hold the raw data for the help messages so their class needs to be queried by mine each time it is run with the -h option and a given 'mode'. – Jason M Nov 13 '12 at 14:14

1 Answers1

3

What you want to do is handled by argparse's sub-commands. Using sub-commands would imply replacing your --mode option with a sub-command:

prog --mode=1 OPTA OPTB OPTC

would become

prog mode1 OPTA OPTB OPTC

The mode1 sub-command can be given its own help; it is accessed with

prog mode1 -h

Another advantage of this approach is that prog -h lists the possible sub-commands (and an associated description).

Eric O Lebigot
  • 81,422
  • 40
  • 198
  • 249
  • As already stated, I don't think it is. The example given was simplified. I don't know the value of mode until after run time, by then it's too late. This question is about help formatting, not argument passing. – Jason M Dec 03 '12 at 12:30