Issue41769
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2020-09-12 02:38 by rjeffman, last changed 2022-04-11 14:59 by admin.
| Messages (4) | |||
|---|---|---|---|
| msg376764 - (view) | Author: Rafael Guterres Jeffman (rjeffman) | Date: 2020-09-12 02:38 | |
argparse allow the use of `store_true` and `store_false` for positional arguments, and although it is weird, it should be fine, but using either action raises a behavior I believe is wrong.
Given the following Python code:
```
import argparse
arg = argparse.ArgumentParser()
arg.add_argument("opt", action="store_false")
arg.parse_args(["-h"])
```
The output is:
```
usage: t.py [-h]
positional arguments:
opt
optional arguments:
-h, --help show this help message and exit
```
Note that the positional argument is not shown in the `usage` line.
When any string parameter is given, the result is:
```
usage: t.py [-h]
t.py: error: unrecognized arguments:
```
(add to the end of the output the value of the argument.)
Even if the use of a positional value is not the best way to describe boolean parameter (optional arguments provide a much better interface for such values), if argparse is to support positional boolean values they should work as other positional arguments.
I'd suggest raising an error if store_true or store_false is used along with positional values.
|
|||
| msg377141 - (view) | Author: Terry J. Reedy (terry.reedy) * ![]() |
Date: 2020-09-18 22:12 | |
You think the behavior is wrong. Does it disagree with the doc? If not, this is an design change (enhancement) issue limited to future version. If so, it might be a bug that can be backported. However, when I run the code on Windows with an argument f:\dev\3x>py -3.8 f:/python/a/tem3.py a b usage: tem3.py [-h] ... I do not get an error, but get the same usage message as without. Adding quotes on the command line makes no difference. |
|||
| msg377241 - (view) | Author: paul j3 (paul.j3) * ![]() |
Date: 2020-09-21 04:01 | |
'store_true/false' are subclasses of 'store_const'. All have a 'nargs=0' value. It's that value which explains their behavior. ('append_const' would also fall in this category)
In [2]: parser = argparse.ArgumentParser()
In [3]: parser.add_argument('foo', action='store_const', default='xxx', const='yyy')
Out[3]: _StoreConstAction(option_strings=[], dest='foo', nargs=0, const='yyy', default='xxx', type=None, choices=None, help=None, metavar=None)
In [4]: _.required
Out[4]: True
In [5]: parser.print_help()
usage: ipython3 [-h]
positional arguments:
foo
optional arguments:
-h, --help show this help message and exit
In [6]: parser.parse_args([])
Out[6]: Namespace(foo='yyy')
In [7]: parser.parse_args(['zzz'])
usage: ipython3 [-h]
ipython3: error: unrecognized arguments: zzz
---
Like '*' and '?' this argument is 'satisfied' with nothing, an empty list of values. For those nargs, 'get_values' takes a the special step of assigning the default. For 'store_const' it's the 'const' that's placed in the namespace. 'store_true' does store True, and 'store_false' does store False.
Providing a string produces an error because there isn't any Action to consume it. With nargs=0, this Action can't use it. Usage is also correct since we can't provide any string to meet this Action's needs.
Technically then the Action behaves correctly - both in usage and what it does. That said, it normally isn't useful, since it will always assign the 'const/True/False' to the namespace. Even without an in depth knowledge of how parsing is done, this should be logically evident (if not obvious).
I don't recall any previous issues like this, though I wouldn't be surprised if there were. I don't recall anything on Stackoverflow either.
I think adding an error would be overkill. It doesn't come up often, and some user might have their own obscure reason for using it.
A note to the docs might be in order, but until a user has encountered this behavior as you have, such a note might be more confusing than useful.
As a general rule, parameter checking in add_argument() is rather loose (and multilayered). While 'action' is used to select the Action subclass, most of the rest are passed on to that Action. The Action __init__ check a few key parameters (for example 'store_const' will complain if we don't provide a 'const'), but accept or ignore the rest.
|
|||
| msg377258 - (view) | Author: Rafael Guterres Jeffman (rjeffman) | Date: 2020-09-21 14:45 | |
I don't think many users will try to use a boolean positional argument. I only excited this behavior because I was writing an abstraction over argparse to define the command line interface based on a configuration file, and I was trying to add some type checking. I think documenting the behavior is enough. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:59:35 | admin | set | github: 85935 |
| 2020-09-21 14:45:29 | rjeffman | set | messages: + msg377258 |
| 2020-09-21 04:01:01 | paul.j3 | set | nosy:
+ paul.j3 messages: + msg377241 |
| 2020-09-18 22:12:09 | terry.reedy | set | nosy:
+ terry.reedy title: Positional arguments which use store boolean actions do not behave as other actions. -> Positional arguments with boolean actions behave differently messages: + msg377141 stage: test needed |
| 2020-09-12 02:38:08 | rjeffman | create | |

