Move "help" to a different Argument Group in python argparse
Question:
Currently I’m creating a directory reader program using Python.
I’m using ‘argparse’ to parse the arguments from command line. I have the following code:
parser = argparse.ArgumentParser(prog = "LS.py",
usage = "%(prog)s [options] [path1 [path2 [...pathN]]]nThe paths are optional; if not given . is used.")
group = parser.add_argument_group("Options")
group.add_argument("-path", default = ".", help = argparse.SUPPRESS, metavar = "")
group.add_argument("-m", "--modified", default = False,
help = "show last modified date/time [default: off]",
metavar = "")
group.add_argument("-o ORDER", "--order=ORDER", nargs = 2, default = "name",
help = "order by ('name', 'n', 'modified', 'm', 'size', 's')n[default: name]",
metavar = "")
group.add_argument("-r", "--recursive", default = False,
help = "recurse into subdirectories [default: off]",
metavar = "")
group.add_argument("-s", "--sizes", default = False,
help = "show sizes [default: off]", metavar = "")
args = parser.parse_args()
return args
When called in the following manner “LS.py -h” it produces the following output:
usage: LS.py [options] [path1 [path2 [...pathN]]]
The paths are optional; if not given . is used.
optional arguments:
-h, --help show this help message and exit
Options:
-m , --modified show last modified date/time [default: off]
-o ORDER , --order=ORDER
order by ('name', 'n', 'modified', 'm', 'size', 's')
[default: name]
-r , --recursive recurse into subdirectories [default: off]
-s , --sizes show sizes [default: off]
My question: Is there a way to move the default help argument into a group such as Options?
Also, I can’t seem to find a way to remove the space before the commas in the Options arguments. The ideal output is:
Usage: ls.py [options] [path1 [path2 [...pathN]]]
The paths are optional; if not given . is used.
Options:
-h, --help show this help message and exit
-m, --modified show last modified date/time [default: off]
-o ORDER, --order=ORDER
order by ('name', 'n', 'modified', 'm', 'size', 's')
[default: name]
-r, --recursive recurse into subdirectories [default: off]
-s, --sizes show sizes [default: off]
Answers:
Sure you can do that. The trick is to just add add_help=False
the the ArgumentParser
constructor and then add your own help action to the group:
import argparse
parser = argparse.ArgumentParser(prog = "LS.py",
usage = "%(prog)s [options] [path1 [path2 [...pathN]]]nThe paths are optional; if not given . is used.",
add_help=False)
group = parser.add_argument_group("Options")
group.add_argument("-path", default = ".", help = argparse.SUPPRESS, metavar = "")
group.add_argument("-m", "--modified", default = False,
help = "show last modified date/time [default: off]",
metavar = "")
group.add_argument("-o ORDER", "--order=ORDER", nargs = 2, default = "name",
help = "order by ('name', 'n', 'modified', 'm', 'size', 's')n[default: name]",
metavar = "")
group.add_argument("-h", "--help", action='help', help='print this fabulous help message')
group.add_argument("-r", "--recursive", default = False,
help = "recurse into subdirectories [default: off]",
metavar = "")
group.add_argument("-s", "--sizes", default = False,
help = "show sizes [default: off]", metavar = "")
args = parser.parse_args()
You can use add_help=False
to disable the built-in help command and add your own instead, using action="help"
(thanks @mgilson!)
To get rid of the spaces, don’t set metavar
to an empty string. Your options should be specified using action="store_true"
to make them true (argument-less) options:
import argparse
parser = argparse.ArgumentParser(prog="LS.py",
usage="%(prog)s [options] [paths...]nThe paths are optional; if not given . is used.",
add_help=False)
group = parser.add_argument_group("Options")
group.add_argument("-h", "--help", action="help", help="show this help message and exit")
group.add_argument("-path", default=".", help=argparse.SUPPRESS)
group.add_argument("-m", "--modified", action="store_true",
help="show last modified date/time")
group.add_argument("-o", "--order", nargs=1, default="name",
help="sort order (n[ame], m[odified], s[ize])n[default: name]")
group.add_argument("-r", "--recursive", action="store_true",
help="recurse into subdirectories")
group.add_argument("-s", "--sizes", action="store_true",
help="show sizes")
args = parser.parse_args()
Output:
Options:
-h, --help show this help message and exit
-m, --modified show last modified date/time
-o ORDER, --order ORDER
sort order (n[ame], m[odified], s[ize]) [default:
name]
-r, --recursive recurse into subdirectories
-s, --sizes show sizes
To condense and simplify a bit upon the previous answer by nneonneo, you can have:
import argparse
parser = argparse.ArgumentParser(prog="LS.py",
usage="%(prog)s [options] [paths...]nThe paths are optional; if not given . is used.",
add_help=False)
add_arg = parser.add_argument_group("Options").add_argument
add_arg("-h", "--help", action="help", help="show this help message and exit")
add_arg("-path", default=".", help=argparse.SUPPRESS)
add_arg("-m", "--modified", action="store_true",
help="show last modified date/time")
add_arg("-o", "--order", nargs=1, default="name",
help="sort order (n[ame], m[odified], s[ize])n[default: name]")
add_arg("-r", "--recursive", action="store_true",
help="recurse into subdirectories")
add_arg("-s", "--sizes", action="store_true",
help="show sizes")
args = parser.parse_args()
Basically, the slight variation from the previous answer is that it is not necessary to save group
and then repeatedly call the the add_argument
method on it.
In my case, I’m working in a module of a larger application that creates the ArgumentParser
object for me so setting add_help=False
isn’t an option. I can set that variable on the ArgumentParser
object but that doesn’t do any good; the help argument has already been created. Instead, I did this (horrible, unsupported hack) to move it from the default "optional arguments" group into my own "Other arguments" group:
if '_action_groups' in parser.__dict__
and 4 == len(parser._action_groups)
and 'optional arguments' == parser._action_groups[1].title
and 'Other arguments' == parser._action_groups[3].title
and '_group_actions' in parser._action_groups[1].__dict__:
act = next((x for x in parser._action_groups[1]._group_actions if 'help' == x.dest), None)
if None != act:
parser._action_groups[1]._group_actions.remove(act)
parser._action_groups[3]._group_actions.append(act)
Any and all of that may break in the next release of Python, but hopefully all of my checks will prevent any such changes from crashing the program and just make "–help" in the default "optional arguments" group.
A better version of this would search for the "optional arguments" and "Other arguments" groups rather than assuming that they’re at indices 0 and 3.
Currently I’m creating a directory reader program using Python.
I’m using ‘argparse’ to parse the arguments from command line. I have the following code:
parser = argparse.ArgumentParser(prog = "LS.py",
usage = "%(prog)s [options] [path1 [path2 [...pathN]]]nThe paths are optional; if not given . is used.")
group = parser.add_argument_group("Options")
group.add_argument("-path", default = ".", help = argparse.SUPPRESS, metavar = "")
group.add_argument("-m", "--modified", default = False,
help = "show last modified date/time [default: off]",
metavar = "")
group.add_argument("-o ORDER", "--order=ORDER", nargs = 2, default = "name",
help = "order by ('name', 'n', 'modified', 'm', 'size', 's')n[default: name]",
metavar = "")
group.add_argument("-r", "--recursive", default = False,
help = "recurse into subdirectories [default: off]",
metavar = "")
group.add_argument("-s", "--sizes", default = False,
help = "show sizes [default: off]", metavar = "")
args = parser.parse_args()
return args
When called in the following manner “LS.py -h” it produces the following output:
usage: LS.py [options] [path1 [path2 [...pathN]]]
The paths are optional; if not given . is used.
optional arguments:
-h, --help show this help message and exit
Options:
-m , --modified show last modified date/time [default: off]
-o ORDER , --order=ORDER
order by ('name', 'n', 'modified', 'm', 'size', 's')
[default: name]
-r , --recursive recurse into subdirectories [default: off]
-s , --sizes show sizes [default: off]
My question: Is there a way to move the default help argument into a group such as Options?
Also, I can’t seem to find a way to remove the space before the commas in the Options arguments. The ideal output is:
Usage: ls.py [options] [path1 [path2 [...pathN]]]
The paths are optional; if not given . is used.
Options:
-h, --help show this help message and exit
-m, --modified show last modified date/time [default: off]
-o ORDER, --order=ORDER
order by ('name', 'n', 'modified', 'm', 'size', 's')
[default: name]
-r, --recursive recurse into subdirectories [default: off]
-s, --sizes show sizes [default: off]
Sure you can do that. The trick is to just add add_help=False
the the ArgumentParser
constructor and then add your own help action to the group:
import argparse
parser = argparse.ArgumentParser(prog = "LS.py",
usage = "%(prog)s [options] [path1 [path2 [...pathN]]]nThe paths are optional; if not given . is used.",
add_help=False)
group = parser.add_argument_group("Options")
group.add_argument("-path", default = ".", help = argparse.SUPPRESS, metavar = "")
group.add_argument("-m", "--modified", default = False,
help = "show last modified date/time [default: off]",
metavar = "")
group.add_argument("-o ORDER", "--order=ORDER", nargs = 2, default = "name",
help = "order by ('name', 'n', 'modified', 'm', 'size', 's')n[default: name]",
metavar = "")
group.add_argument("-h", "--help", action='help', help='print this fabulous help message')
group.add_argument("-r", "--recursive", default = False,
help = "recurse into subdirectories [default: off]",
metavar = "")
group.add_argument("-s", "--sizes", default = False,
help = "show sizes [default: off]", metavar = "")
args = parser.parse_args()
You can use add_help=False
to disable the built-in help command and add your own instead, using action="help"
(thanks @mgilson!)
To get rid of the spaces, don’t set metavar
to an empty string. Your options should be specified using action="store_true"
to make them true (argument-less) options:
import argparse
parser = argparse.ArgumentParser(prog="LS.py",
usage="%(prog)s [options] [paths...]nThe paths are optional; if not given . is used.",
add_help=False)
group = parser.add_argument_group("Options")
group.add_argument("-h", "--help", action="help", help="show this help message and exit")
group.add_argument("-path", default=".", help=argparse.SUPPRESS)
group.add_argument("-m", "--modified", action="store_true",
help="show last modified date/time")
group.add_argument("-o", "--order", nargs=1, default="name",
help="sort order (n[ame], m[odified], s[ize])n[default: name]")
group.add_argument("-r", "--recursive", action="store_true",
help="recurse into subdirectories")
group.add_argument("-s", "--sizes", action="store_true",
help="show sizes")
args = parser.parse_args()
Output:
Options:
-h, --help show this help message and exit
-m, --modified show last modified date/time
-o ORDER, --order ORDER
sort order (n[ame], m[odified], s[ize]) [default:
name]
-r, --recursive recurse into subdirectories
-s, --sizes show sizes
To condense and simplify a bit upon the previous answer by nneonneo, you can have:
import argparse
parser = argparse.ArgumentParser(prog="LS.py",
usage="%(prog)s [options] [paths...]nThe paths are optional; if not given . is used.",
add_help=False)
add_arg = parser.add_argument_group("Options").add_argument
add_arg("-h", "--help", action="help", help="show this help message and exit")
add_arg("-path", default=".", help=argparse.SUPPRESS)
add_arg("-m", "--modified", action="store_true",
help="show last modified date/time")
add_arg("-o", "--order", nargs=1, default="name",
help="sort order (n[ame], m[odified], s[ize])n[default: name]")
add_arg("-r", "--recursive", action="store_true",
help="recurse into subdirectories")
add_arg("-s", "--sizes", action="store_true",
help="show sizes")
args = parser.parse_args()
Basically, the slight variation from the previous answer is that it is not necessary to save group
and then repeatedly call the the add_argument
method on it.
In my case, I’m working in a module of a larger application that creates the ArgumentParser
object for me so setting add_help=False
isn’t an option. I can set that variable on the ArgumentParser
object but that doesn’t do any good; the help argument has already been created. Instead, I did this (horrible, unsupported hack) to move it from the default "optional arguments" group into my own "Other arguments" group:
if '_action_groups' in parser.__dict__
and 4 == len(parser._action_groups)
and 'optional arguments' == parser._action_groups[1].title
and 'Other arguments' == parser._action_groups[3].title
and '_group_actions' in parser._action_groups[1].__dict__:
act = next((x for x in parser._action_groups[1]._group_actions if 'help' == x.dest), None)
if None != act:
parser._action_groups[1]._group_actions.remove(act)
parser._action_groups[3]._group_actions.append(act)
Any and all of that may break in the next release of Python, but hopefully all of my checks will prevent any such changes from crashing the program and just make "–help" in the default "optional arguments" group.
A better version of this would search for the "optional arguments" and "Other arguments" groups rather than assuming that they’re at indices 0 and 3.