Consider the following toy example:
cat extended_help.py
import argparse
ap = argparse.ArgumentParser()
ap.add_argument("-H", "--help-all", action = "version",
help = """show extended help message (incl. advanced
parameters) and exit""",
version = "This is just a dummy implementation.")
common_args = ap.add_argument_group("common parameters",
"""These parameters are typically
enough to run the tool. `%(prog)s
-h|--help` should list these
parameters.""")
advanced_args = ap.add_argument_group("advanced parameters",
"""These parameters are for advanced
users with special needs only. To make
the help more accessible, `%(prog)s
-h|--help` should not include these
parameters, while `%(prog)s
-H|--help-all` should include them (in
addition to those included by `%(prog)s
-h|--help`.""")
common_args.add_argument("-f", "--foo", metavar = "<foo>",
help = "the very common Foo parameter")
common_args.add_argument("--flag", action = "store_true",
help = "a flag enabling a totally normal option")
advanced_args.add_argument("-b", "--bar", metavar = "<bar>",
help = "the rarely needed Bar parameter")
advanced_args.add_argument("-B", "--baz", metavar = "<bar>",
help = "the even more obscure Baz parameter")
advanced_args.add_argument("--FLAG", action = "store_true",
help = "a flag for highly advanced users only")
ap.parse_args()
python extended_help.py -h
prints
usage: extended_help.py [-h] [-H] [-f <foo>] [--flag] [-b <bar>] [-B <bar>] [--FLAG]
options:
-h, --help show this help message and exit
-H, --help-all show extended help message (incl. advanced parameters) and exit
common parameters:
These parameters are typically enough to run the tool. `extended_help.py -h|--help` should list these parameters.
-f, --foo <foo> the very common Foo parameter
--flag a flag enabling a totally normal option
advanced parameters:
These parameters are for advanced users with special needs only. To make the help more accessible, `extended_help.py -h|--help` should not include these parameters, while
`extended_help.py -H|--help-all` should include them (in addition to those included by `extended_help.py -h|--help`.
-b, --bar <bar> the rarely needed Bar parameter
-B, --baz <bar> the even more obscure Baz parameter
--FLAG a flag for highly advanced users only
while
python extended_help.py -H
only generates the placeholder message
This is just a dummy implementation.
How would I need to modify extended_help.py to have
python extended_help.py -h
print only
usage: extended_help.py [-h] [-H] [-f <foo>] [--flag] [-b <bar>] [-B <bar>] [--FLAG]
options:
-h, --help show this help message and exit
-H, --help-all show extended help message (incl. advanced parameters) and exit
common parameters:
These parameters are typically enough to run the tool. `extended_help.py -h|--help` should list these parameters.
-f, --foo <foo> the very common Foo parameter
--flag a flag enabling a totally normal option
and have
python extended_help.py -H
reproduce the full help message currently printed by
python extended_help.py -h
?
I am looking for a solution that avoids manually duplicating the help message(s of certain arguments).
edit:
I know I can make -H replace -h as follows:
import argparse
ap = argparse.ArgumentParser(add_help = False)
ap.add_argument("-h", "--help", action = "version",
help = "show help message (common parameters only) and exit",
version = """I know I could add the entire (short) help here
but I'd like to avoid that.""")
ap.add_argument("-H", "--help-all", action = "help",
help = """show extended help message (incl. advanced
parameters) and exit""")
common_args = ap.add_argument_group("common parameters",
"""These parameters are typically
enough to run the tool. `%(prog)s
-h|--help` should list these
parameters.""")
# The rest would be the same as above.
This way,
python extended_help.py -H
already works as intended:
usage: extended_help.py [-h] [-H] [-f <foo>] [--flag] [-b <bar>] [-B <bar>] [--FLAG]
options:
-h, --help show help message (common parameters only) and exit
-H, --help-all show extended help message (incl. advanced parameters) and exit
common parameters:
These parameters are typically enough to run the tool. `extended_help.py -h|--help` should list these parameters.
-f, --foo <foo> the very common Foo parameter
--flag a flag enabling a totally normal option
advanced parameters:
These parameters are for advanced users with special needs only. To make the help more accessible, `extended_help.py -h|--help` should not include these parameters, while
`extended_help.py -H|--help-all` should include them (in addition to those included by `extended_help.py -h|--help`.
-b, --bar <bar> the rarely needed Bar parameter
-B, --baz <bar> the even more obscure Baz parameter
--FLAG a flag for highly advanced users only
However, now
python extended_help.py -h
only prints a placeholder:
I know I could add the entire help here but I'd like to avoid that.
update:
I managed to get quite close:
import argparse
ap = argparse.ArgumentParser(add_help = False, conflict_handler = "resolve")
ap.add_argument("-h", "--help", action = "help",
help = "show help message (common parameters only) and exit")
ap.add_argument("-H", "--help-all", action = "help",
help = """show extended help message (incl. advanced
parameters) and exit""")
common_args = ap.add_argument_group("common parameters",
"""These parameters are typically
enough to run the tool. `%(prog)s
-h|--help` should list these
parameters.""")
common_args.add_argument("-f", "--foo", metavar = "<foo>",
help = "the very common Foo parameter")
common_args.add_argument("--flag", action = "store_true",
help = "a flag enabling a totally normal option")
ap.add_argument("-h", "--help", action = "version", version = ap.format_help())
advanced_args = ap.add_argument_group("advanced parameters",
"""These parameters are for advanced
users with special needs only. To make
the help more accessible, `%(prog)s
-h|--help` should not include these
parameters, while `%(prog)s
-H|--help-all` should include them (in
addition to those included by `%(prog)s
-h|--help`.""")
advanced_args.add_argument("-b", "--bar", metavar = "<bar>",
help = "the rarely needed Bar parameter")
advanced_args.add_argument("-B", "--baz", metavar = "<bar>",
help = "the even more obscure Baz parameter")
advanced_args.add_argument("--FLAG", action = "store_true",
help = "a flag for highly advanced users only")
ap.parse_args()
This captures the help message before adding the advanced arguments and overwrites the -h|--help flag's 'version' string (ab-)used to store/print the short help.
python extended_help.py -H
already works as intended, but
python extended_help.py -h
swallows all line breaks and spaces from the help message:
usage: extended_help.py [-h] [-H] [-f <foo>] [--flag] options: -h, --help show help message (common parameters only) and exit -H, --help-all show extended help message (incl.
advanced parameters) and exit common parameters: These parameters are typically enough to run the tool. `extended_help.py -h|--help` should list these parameters. -f, --foo
<foo> the very common Foo parameter --flag a flag enabling a totally normal option
update:
The problem remaining in the version above turned out to be related to me abusing the version action. I solved it by defining my own custom action for the short help ('inspired' by the help action implementation in the argparse module itself).
I'll leave the above steps here for documentation reasons. Feel free to clean up the question (or prompt me to do so), if preferred.
Any feedback to my solution or alternative suggestions would be welcome.
versionat all? You found thehelpaction option. Have you explored the alternative 'help_formatters'? You may need to explore theargparse.pycode, such as methods likeformat_help. And how the alternative formatters work.