Title: ArgumentParser should support bool type according to truth values
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.9, Python 3.8, Python 3.7, Python 3.6, Python 3.5, Python 2.7
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Zach Beniash, matrixise, paul.j3
Priority: normal Keywords: patch

Created on 2019-07-11 15:10 by Zach Beniash, last changed 2019-09-13 12:19 by matrixise.

Pull Requests
URL Status Linked Edit
PR 14709 open python-dev, 2019-07-11 15:15
Messages (5)
msg347686 - (view) Author: Zach Beniash (Zach Beniash) * Date: 2019-07-11 15:10
Today when using argparse.ArgumentParser it seems that the bool type is not supported in a logical way.
Foe example:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--mybool", type=bool)
parsed_args = parser.parse(["--mybool", "False"])
parsed_args.my_bool evaluates to True

Instead we should expect to evaluate False here.
msg347704 - (view) Author: paul j3 (paul.j3) * (Python triager) Date: 2019-07-11 20:06
This is an old topic, though it may be easier to find a relevant StackOverflow thread.  (a 2013 thread)

I and others have explained that the `type` parameter is supposed to be a callable.  The default Python `bool` function only returns False for an empty string.  Previous discussions have suggested writing a function that parses strings like 'False' and 'No'.  It's nice that you have found a 'distutils.utils.strtobool' that does this well.

But I have several qualms about the proposed patch:

- do we need to define a 'bool' type?  We already has 'store_true' and 'store_false' actions.

- does this function need a 'bool' wrapper?

- do we need another import?  There's a relatively recent bug/issue that tries to speed up argparse by reducing the number of imports.

- if added, should this type be registered as the object bool or string 'bool'?  

Seems to me that the patch could be simplified to:

     self.register('type', 'bool', _strtobool)

According the original developer `type=bool` should be allowed (even if it doesn't do what many users expect):

I point out that users are used to providing strings for 'action', but not for 'type'.  The registry mechanism can be used to provide specialized type but so far only 'None' is registered.

This proposed patch might be innocuous, but it does break a consistent behavior - that 'type' should be a callable, and 'bool' is a standard Python function.

An alternative is to add to the docs a note (in the 'type' section) that

    from distutils.util import strtobool

could be used to parse strings as booleans.
msg347989 - (view) Author: paul j3 (paul.j3) * (Python triager) Date: 2019-07-15 19:21
The use of `bool` as registry key only works because that object already exists as a builtin.  This amounts a form of shadowing, and sets a dangerous precedent.


should work as documented at

even if that is not what a casual user would expect.
msg349476 - (view) Author: paul j3 (paul.j3) * (Python triager) Date: 2019-08-12 15:40
This patch lacks proper documentation, and is too English language specific.

For users who assume 'type' means a class rather than function (callable) this change does not need documentation, since it accommodates that assumption.  But more experienced users, or ones who read the documentation with care, this change could be puzzling.  "Why does 'bool' work?"  Admittedly they are unlikely to try it.  Still, we are deviating the documented behavior.

We also need to pay attention to internationalization.  Argparse wraps most error messages and string displays in 'gettext'.  There isn't any other part of argparse that assumes that sys.argv strings have English meanings.
msg352308 - (view) Author: Stéphane Wirtel (matrixise) * (Python committer) Date: 2019-09-13 12:19
What will happen if we want to translate "true", "yes", ...?

Date User Action Args
2019-09-13 12:19:21matrixisesetnosy: + matrixise
messages: + msg352308
2019-08-12 15:40:58paul.j3setmessages: + msg349476
2019-07-15 19:21:32paul.j3setmessages: + msg347989
2019-07-11 20:06:49paul.j3setmessages: + msg347704
2019-07-11 15:24:42xtreaksetnosy: + paul.j3
2019-07-11 15:15:09python-devsetkeywords: + patch
stage: patch review
pull_requests: + pull_request14509
2019-07-11 15:10:32Zach Beniashcreate