Skip to content

Commit b239bb7

Browse files
committed
gh-126676: Expand argparse docs for type=bool with warning and alternatives
1 parent 9343518 commit b239bb7

File tree

2 files changed

+56
-3
lines changed

2 files changed

+56
-3
lines changed

Doc/library/argparse.rst

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,9 +1116,58 @@ User defined functions can be used as well:
11161116
>>> parser.parse_args(['"The Tale of Two Cities"'])
11171117
Namespace(short_title='"the-tale-of-two-citi')
11181118

1119-
The :func:`bool` function is not recommended as a type converter. All it does
1120-
is convert empty strings to ``False`` and non-empty strings to ``True``.
1121-
This is usually not what is desired.
1119+
.. warning::
1120+
1121+
The :func:`bool` function is not recommended as a type converter. All it
1122+
does is convert empty strings to ``False`` and non-empty strings to
1123+
``True``. This is usually not what is desired::
1124+
1125+
>>> parser = argparse.ArgumentParser()
1126+
>>> _ = parser.add_argument('--verbose', type=bool)
1127+
>>> parser.parse_args(['--verbose', 'False'])
1128+
Namespace(verbose=True)
1129+
1130+
``'False'`` is a non-empty string, so :func:`bool` converts it to
1131+
``True``.
1132+
1133+
To handle boolean flags, use one of the following patterns instead:
1134+
1135+
* For ``--flag``/``--no-flag`` style options, use
1136+
:class:`BooleanOptionalAction`::
1137+
1138+
>>> parser = argparse.ArgumentParser()
1139+
>>> _ = parser.add_argument('--verbose', action=argparse.BooleanOptionalAction)
1140+
>>> parser.parse_args(['--verbose'])
1141+
Namespace(verbose=True)
1142+
>>> parser.parse_args(['--no-verbose'])
1143+
Namespace(verbose=False)
1144+
1145+
* For a flag that sets a ``True`` or ``False`` value, use
1146+
``action='store_true'`` or ``action='store_false'``::
1147+
1148+
>>> parser = argparse.ArgumentParser()
1149+
>>> _ = parser.add_argument('--verbose', action='store_true')
1150+
>>> parser.parse_args(['--verbose'])
1151+
Namespace(verbose=True)
1152+
>>> parser.parse_args([])
1153+
Namespace(verbose=False)
1154+
1155+
* For a positional or option that accepts the strings ``'true'`` or
1156+
``'false'``, define a converter function::
1157+
1158+
>>> def str_to_bool(value):
1159+
... if value.casefold() in ('true', '1', 'yes'):
1160+
... return True
1161+
... elif value.casefold() in ('false', '0', 'no'):
1162+
... return False
1163+
... raise argparse.ArgumentTypeError(f'{value!r} is not a boolean value')
1164+
...
1165+
>>> parser = argparse.ArgumentParser()
1166+
>>> _ = parser.add_argument('--verbose', type=str_to_bool)
1167+
>>> parser.parse_args(['--verbose', 'yes'])
1168+
Namespace(verbose=True)
1169+
>>> parser.parse_args(['--verbose', 'false'])
1170+
Namespace(verbose=False)
11221171

11231172
In general, the ``type`` keyword is a convenience that should only be used for
11241173
simple conversions that can only raise one of the three supported exceptions.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Expand :mod:`argparse` documentation for ``type=bool`` with a warning
2+
admonition, a demonstration of the surprising behavior, and recommended
3+
alternatives (``BooleanOptionalAction``, ``store_true``/``store_false``,
4+
and a custom converter function).

0 commit comments

Comments
 (0)