I can explain what is going on, but may not be able offer a solution.
The short answer is that the sp1.prog
is used both in its usage
format and as the %(prog)s
value in the help lines. And it is constructed with that usage
line in mind.
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2])
creates a parser, and adds arguments from the parents
. add_parser
is a method of the class _SubParsersAction
(the subparser Action class). And the prog
attribute for that parser is created with:
if kwargs.get('prog') is None:
kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
You should be able to see this attribute with print(sp1.prog)
(I expect 'master prog1'). That's the value that is used in the usage
line, and in any of the help lines with %(prog)s
.
subparsers._prog_prefix
is derived from parser.prog
(see the add_subparsers
code for details). But you can also specify a prog
parameter:
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='prog1')
That should correct the string in the help
line. But it will also change the string the usage
.
You could also give the subparser an explicit usage
:
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='prog1', usage='master prog1 ...')
Without doing surgery to the HelpFormatter
I don't think you can change prog
in the help lines without also changing it in the usage.
And given the way parents
works you can't change the help line for prog1 foo
without also changing it for prog2 foo
. parents
copies Action objects by reference, so the two subparsers share the foo
Action object.
You many have to abandon the parents
approach, at least for this argument, and hardcode the name. If you need to add the argument to multiple subparsers, write a little utility function to facilitate that. The parents
mechanism is just (usually) a convenience, something that saves some typing/editing.
This modified script will illustrate my points
parser = ArgumentParser(prog = 'master')
parser1 = ArgumentParser(add_help = False)
fooarg=parser1.add_argument('foo', type = int, help = 'foo prog: %(prog)s') # Line of interest
parser2 = ArgumentParser(add_help = False)
parser2.add_argument('--bar', type = int, default = 0, help = 'Start at this number')
parser3 = ArgumentParser(add_help = False)
parser3.add_argument('--baz', type = str, default = 'DEFAULT', help = 'Init file with this text')
subparsers = parser.add_subparsers(prog='subparsers')
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='name1')
sp2 = subparsers.add_parser('prog2', parents = [parser1, parser3])
#parser.print_help()
# fooarg is an Action for both subparsers
# print(fooarg.help)
# fooarg.help = 'FOO HELP'
print('==>sp1 prog:', sp1.prog)
sp1.print_help()
print('==>sp2 prog:', sp2.prog)
sp2.print_help()
sp1.prog = 'custom'
sp1.print_help()
# addition
fooarg.default = 'default'
fooarg.metavar = 'META'
fooarg.help = 'prog: %(prog)s, dest=%(dest)s, nargs=%(nargs)s, type=%(type)s, default=%(default)s'
sp1.print_help()
This last bit adds a bunch of Action attributes to the help. But prog
is the only one that comes from the parser
:
positional arguments:
META prog: custom, dest=foo, nargs=None, type=int, default=default