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.

classification
Title: argparse values for action in add_argument() should be flags instead of (or in addition to) strings
Type: enhancement Stage: resolved
Components: Versions: Python 3.7, Python 3.6, Python 2.7
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: Nosy List: paul.j3, pgacv2, r.david.murray
Priority: normal Keywords:

Created on 2017-02-23 13:31 by pgacv2, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (4)
msg288445 - (view) Author: Pedro (pgacv2) Date: 2017-02-23 13:31
The possible values for action are currently:
'store'
'store_true'
'store_false'
'store_const'
'append'
'append_const'
'count'
'help'
'version'
a subclass of argparse.Action

The string values are evidently for backward compatibility with optparse. However, adding the ability to specify these options as flags would make argparse code more maintainable (e.g. IDEs are better at refactoring symbols than strings), bring it in line with other places where a module has built-in flags, like the regex module (re.MULTILINE, re.IGNORECASE, etc.), and expand the use of flags that already exist in argparse (e.g. argparse.SUPPRESS, argparse.REMAINDER).

The string values need not be immediately deprecated, but can be made available as the preferred option for new development. See, for example, getName() and setName() in the threading module, which are documented as follows: "Old getter/setter API for name; use it directly as a property instead." A similar suggestion can be provided for argparse flags: "Old action values for backward compatibility; use the flags instead."
msg288457 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-02-23 15:51
The obvious thing to do would be to make the Action subclasses have public names.  I personally would continue to use the strings, though, as they are easier to type.  (The same would be true if an enum were introduced (that I'd continue to use the stings because they are easier to type :), since they would need to be namespaced (argparse.action.store_true, for example).)

I can see some potential value in exposing the action subclasses, but I'm not sure if it is worth it.
msg288500 - (view) Author: paul j3 (paul.j3) * (Python triager) Date: 2017-02-24 02:08
Those strings are defined in a 'parser.registry' dictionary, with expressions like

    self.register('action', 'store', _StoreAction)

(Users can also register their own custom classes. The registry can also be used for the 'type' attribute.)

So you can already do:

    parser.add_argument('--foo', action=argparse._StoreAction)

So I don't think we need another mapping like

    argparse.STORE_ACTION = argparse._StoreAction

I think these Action subclasses are not part of the API because users should never instantiate one directly.  It should always be done via the 'add_argument' method.

But on occasion it is handy to grab one of the Action objects when it is returned by add_argument, and display or even modify one of its attributes.  Some users are reluctant to do so because that's not documented.

Some of the `nargs` values have constants names in addition to the string values.  

argparse.REMAINDER = '...'
argparse.OPTIONAL = '?'
so on for '+', '*', and even '+...'.  Users almost always use the strings, while the code always uses the constant.

But because `argparse._StoreAction` is a class, with its own defined methods, there's never a need to test for its 'value' or identity.  So the code does not need a `argparse.STORE_ACTION flag.

So for end users, and for internal code use, the current use of subclasses and the registry is works, and doesn't need to be changed just to look more like other modules.
msg290149 - (view) Author: Pedro (pgacv2) Date: 2017-03-24 21:54
I guess I'm a little allergic to magic strings. I think there is value in greater consistency across modules, but agree it's not a big deal because the Action classes are already accessible that way.

I was unaware of the details behind `action` and actually just found an opportunity to use an Action subclass, so thank you for clarifying.
History
Date User Action Args
2022-04-11 14:58:43adminsetgithub: 73818
2017-03-24 21:55:01pgacv2setstatus: open -> closed
resolution: wont fix
stage: resolved
2017-03-24 21:54:26pgacv2setmessages: + msg290149
2017-02-24 02:08:13paul.j3setmessages: + msg288500
2017-02-24 01:09:15paul.j3setnosy: + paul.j3
2017-02-23 15:51:11r.david.murraysetnosy: + r.david.murray
messages: + msg288457
2017-02-23 13:31:07pgacv2create