classification
Title: argparse: Default Help Message Lists Required Args As Optional
Type: enhancement Stage: needs patch
Components: Documentation Versions: Python 3.3, Python 3.2, Python 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: benschmaus, bethard, docs@python, eric.araujo, eric.smith, r.david.murray, terry.reedy
Priority: normal Keywords:

Created on 2010-08-26 18:19 by benschmaus, last changed 2011-03-27 23:24 by eric.araujo.

Files
File name Uploaded Description Edit
argparse-help-says-required-args-are-optional.py benschmaus, 2010-08-26 18:19
Messages (16)
msg115017 - (view) Author: Ben Schmaus (benschmaus) Date: 2010-08-26 18:19
The argparse module lists required args as optional in the default help message.

If you run the following program (also attached) you'll get the output listed below.

#!/usr/bin/env python

import argparse

parser = argparse.ArgumentParser(
    description = 'Do something'
)
parser.add_argument('--reqarg', '-r', help = 'This is required', required = True)
parser.add_argument('--optarg','-o', help = "This is optional", required = False)
args = parser.parse_args()

$ python argparse-help-says-required-args-are-optional.py -h
usage: argparse-help-says-required-args-are-optional.py [-h] --reqarg REQARG
                                                        [--optarg OPTARG]

Do something

optional arguments:
  -h, --help            show this help message and exit
  --reqarg REQARG, -r REQARG
                        This is required
  --optarg OPTARG, -o OPTARG
                        This is optional
$
msg115019 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2010-08-26 18:32
It looks to me like reqarg is marked as required, since it's not in brackets. Or am I missing something?
msg115021 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-08-26 18:44
Yeah, the fact that it is listed under the heading "optional arguments:" :)  Guess we need a new section?
msg115023 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2010-08-26 19:04
Duh. Sorry about that.

Also applies to 3.2.
msg115032 - (view) Author: Steven Bethard (bethard) * (Python committer) Date: 2010-08-26 21:54
Yeah, I guess the optional vs. positional isn't the best terminology now that you can have required flag-based arguments. Did you have a word other than "optional" that you'd prefer?
msg115037 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-08-26 22:35
Perhaps you could just label them 'options:'?  After all, even if you have several options you may be required to pick at least one :)
msg115038 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2010-08-26 22:41
Or "parameters:"?
msg115045 - (view) Author: Ben Schmaus (benschmaus) Date: 2010-08-26 23:25
FWIW, I like the idea of just using the label "options".
msg115048 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2010-08-27 00:14
If you add a positional parameter by adding:
parser.add_argument('foo')
then the output becomes:

$ python argparse-help-says-required-args-are-optional.py -h
usage: issue9649.py [-h] --reqarg REQARG [--optarg OPTARG] foo

Do something

positional arguments:
  foo

optional arguments:
  -h, --help            show this help message and exit
  --reqarg REQARG, -r REQARG
                        This is required
  --optarg OPTARG, -o OPTARG
                        This is optional

$

So whatever replaces "optional arguments:" needs to read well with "positional arguments:". Maybe just plain "options:" is good enough, but I think a word to replace "optional" (leaving "arguments:") would be better. I just don't have any useful suggestion :)
msg115058 - (view) Author: Steven Bethard (bethard) * (Python committer) Date: 2010-08-27 08:48
I guess one possibility might be "flag arguments". It's not great, but I guess it's more accurate.
msg115059 - (view) Author: Steven Bethard (bethard) * (Python committer) Date: 2010-08-27 08:57
And I guess the bigger issue to think about is how to add this in a backwards compatible way. I guess we could just add methods like "set_positionals_group_name(name)" and then fiddle with "self._positionals.title" in there. Not sure that's a great solution though - it seems like adding one method to change just this single attribute is overkill and not very general.

In the meantime, here's a workaround:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', required=True)
>>> parser._optionals.title = "flag arguments"
>>> parser.print_help()
usage: PROG [-h] --foo FOO

flag arguments:
  -h, --help  show this help message and exit
  --foo FOO

I can't promise this will continue to work, since it uses the undocumented _optionals attribute, but at least it's a way of getting something like what you want now.
msg115069 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-08-27 12:47
Well, there's also issue 9652, which speaks to having a more general facility, I suppose.  Maybe an exposed dictionary attribute containing the constant strings?
msg115109 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2010-08-27 18:15
Is this really a behavior bug or doc bug?
Or a feature request for better message customization?
msg115117 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2010-08-27 19:14
*This* bug is a behavior bug (required flags are mis-labelled as being optional in the help text).  The referenced bug is a feature request, but it may make sense to consider it while fixing this one.
msg115148 - (view) Author: Steven Bethard (bethard) * (Python committer) Date: 2010-08-28 07:03
I think this is still really a feature request. We can't just change the text from "optional" - that would silently change a large number of help messages without any warning. So to fix this "bug", we're going to have to add an API to explicitly set the group names - which can only be done as a new feature. People using 2.7 will have to use the workaround using parser._optionals I posted here.
msg132327 - (view) Author: Steven Bethard (bethard) * (Python committer) Date: 2011-03-27 14:20
So it strikes me that there already exists an officially supported way to rename your option groups. Just only create your own option groups (never use the default ones) and only put arguments there, e.g.:

------------------------- temp.py --------------------------
parser = argparse.ArgumentParser(description = 'Do something', add_help=False)
flags = parser.add_argument_group('flag arguments')
flags.add_argument('-h', '--help', action='help')
flags.add_argument('--reqarg', '-r', help='This is required', required=True)
flags.add_argument('--optarg','-o', help="This is optional", required=False)
args = parser.parse_args()
------------------------------------------------------------
$ python temp.py --help
usage: temp.py [-h] --reqarg REQARG [--optarg OPTARG]

Do something

flag arguments:
  -h, --help
  --reqarg REQARG, -r REQARG
                        This is required
  --optarg OPTARG, -o OPTARG
                        This is optional
------------------------------------------------------------

The documentation for action='help' needs to be added, as pointed out in Issue# 10772.

So basically, the API for customizing group names is already there. So I'm changing this to a documentation request - there should be an example in the docs showing how to change the default group names as above.
History
Date User Action Args
2011-03-27 23:24:15eric.araujosetversions: + Python 2.7, Python 3.2
2011-03-27 14:20:43bethardsetnosy: + docs@python
versions: + Python 3.3, - Python 3.2
messages: + msg132327

assignee: docs@python
components: + Documentation, - Library (Lib)
stage: needs patch
2010-08-28 07:03:42bethardsettype: behavior -> enhancement
messages: + msg115148
versions: - Python 2.7
2010-08-27 23:24:00eric.araujosetnosy: + eric.araujo
2010-08-27 19:14:04r.david.murraysetmessages: + msg115117
2010-08-27 18:15:40terry.reedysetnosy: + terry.reedy
messages: + msg115109
2010-08-27 12:47:51r.david.murraysetmessages: + msg115069
2010-08-27 08:57:05bethardsetmessages: + msg115059
2010-08-27 08:48:47bethardsetmessages: + msg115058
2010-08-27 00:14:38eric.smithsetmessages: + msg115048
2010-08-26 23:25:21benschmaussetmessages: + msg115045
2010-08-26 22:41:23eric.smithsetmessages: + msg115038
2010-08-26 22:35:18r.david.murraysetmessages: + msg115037
2010-08-26 21:54:38bethardsetmessages: + msg115032
2010-08-26 19:04:47eric.smithsetmessages: + msg115023
versions: + Python 3.2
2010-08-26 18:44:12r.david.murraysetnosy: + r.david.murray
messages: + msg115021
2010-08-26 18:32:52eric.smithsetnosy: + bethard, eric.smith
messages: + msg115019
2010-08-26 18:19:17benschmauscreate