I have an application with several dozens of CLI parameters. I use python argparse to parse arguments. Most of them are rarely used, only 5 or 6 are frequent. I don't want to clutter up the output of --help
for simple cases, however there still should be a possibility to see description for all parameters somehow.
It is possible to have several verbosity levels for help in argparse? Here's how I expect it to be.
$ myapp -h
optional arguments:
--foo Do foo stuff
--bar Do bar stuff
$ myapp -hh # or myapp --expert-mode -h
optional arguments:
--foo Do foo stuff
--bar Do bar stuff
expert arguments:
--use-warp-drive
--no-fasten-seatbelts
... 50 more arguments
My first idea was to create two ArgumentParser-s, the basic one and the verbose one. First, parse_args
of the basic was called. If --expert
flag is present, the verbose parser is created and called. The approach has two downsides. First, -h
is unconditionally handled by the first parser, so I should implement my own analogous help flag. Second, expert options are not even parsed without --expert
flag, and I want them to be parsed unconditionally (but not to pop up in help).
Note: the solution should be python2 compliant.
Update: using the ideas from Lior Cohen's answer and this question, I created a working example. In my case it was easier to make a whitelist of "simple" options, so it was even unnecessary to use tagged action types.
Illustrating code follows.
class ExpertHelpFormatter(argparse.HelpFormatter):
skip_expert_section = True
whitelist = set(("foo",))
def add_usage(self, usage, actions, groups, prefix=None):
if self.skip_expert_section:
actions = [action for action in actions if action.dest in self.whitelist]
ret = super(ExpertHelpFormatter, self).add_usage(usage, actions, groups, prefix)
if self.skip_expert_section:
self.add_text("Use -hh for detailed help.")
return ret
def add_argument(self, action):
if self.skip_expert_section and action.dest not in self.whitelist:
return
super(ExpertHelpFormatter, self).add_argument(action)
def main():
parser = argparse.ArgumentParser(add_help=False, formatter_class=ExpertHelpFormatter)
parser.add_argument("-h", "--help", action="count", default=0)
parser.add_argument("--foo")
parser.add_argument("--use-warp-drive", action="store_true")
args = parser.parse_args()
if args.help == 1:
print parser.format_help()
return
elif args.help > 1:
ExpertHelpFormatter.skip_expert_section = False
print parser.format_help()
return