Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-37880: for argparse add_argument with action='store_const', const defaults to None. #26707

Merged
merged 7 commits into from
Jul 31, 2021
27 changes: 16 additions & 11 deletions Doc/library/argparse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -722,8 +722,9 @@ The :meth:`~ArgumentParser.add_argument` method must know whether an optional
argument, like ``-f`` or ``--foo``, or a positional argument, like a list of
filenames, is expected. The first arguments passed to
:meth:`~ArgumentParser.add_argument` must therefore be either a series of
flags, or a simple argument name. For example, an optional argument could
be created like::
flags, or a simple argument name.

For example, an optional argument could be created like::

>>> parser.add_argument('-f', '--foo')

Expand Down Expand Up @@ -765,8 +766,9 @@ how the command-line arguments should be handled. The supplied actions are:
Namespace(foo='1')

* ``'store_const'`` - This stores the value specified by the const_ keyword
argument. The ``'store_const'`` action is most commonly used with
optional arguments that specify some sort of flag. For example::
argument; note that the const_ keyword argument defaults to ``None``. The
``'store_const'`` action is most commonly used with optional arguments that
specify some sort of flag. For example::

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
Expand Down Expand Up @@ -795,8 +797,8 @@ how the command-line arguments should be handled. The supplied actions are:
Namespace(foo=['1', '2'])

* ``'append_const'`` - This stores a list, and appends the value specified by
the const_ keyword argument to the list. (Note that the const_ keyword
argument defaults to ``None``.) The ``'append_const'`` action is typically
the const_ keyword argument to the list; note that the const_ keyword
argument defaults to ``None``. The ``'append_const'`` action is typically
useful when multiple arguments need to store constants to the same list. For
example::

Expand Down Expand Up @@ -977,17 +979,20 @@ the various :class:`ArgumentParser` actions. The two most common uses of it are
``action='store_const'`` or ``action='append_const'``. These actions add the
``const`` value to one of the attributes of the object returned by
:meth:`~ArgumentParser.parse_args`. See the action_ description for examples.
If ``const`` is not provided to :meth:`~ArgumentParser.add_argument`, it will
receive a default value of ``None``.


* When :meth:`~ArgumentParser.add_argument` is called with option strings
(like ``-f`` or ``--foo``) and ``nargs='?'``. This creates an optional
argument that can be followed by zero or one command-line arguments.
When parsing the command line, if the option string is encountered with no
command-line argument following it, the value of ``const`` will be assumed instead.
See the nargs_ description for examples.

With the ``'store_const'`` and ``'append_const'`` actions, the ``const``
keyword argument must be given. For other actions, it defaults to ``None``.
command-line argument following it, the value of ``const`` will be assumed to
be ``None`` instead. See the nargs_ description for examples.

.. versionchanged:: 3.11
``const=None`` by default, including when ``action='append_const'`` or
``action='store_const'``.

default
^^^^^^^
Expand Down
5 changes: 3 additions & 2 deletions Lib/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,7 @@ def format_usage(self):
def __call__(self, parser, namespace, values, option_string=None):
raise NotImplementedError(_('.__call__() not defined'))


class BooleanOptionalAction(Action):
def __init__(self,
option_strings,
Expand Down Expand Up @@ -934,7 +935,7 @@ class _StoreConstAction(Action):
def __init__(self,
option_strings,
dest,
const,
const=None,
default=None,
required=False,
help=None,
Expand Down Expand Up @@ -1029,7 +1030,7 @@ class _AppendConstAction(Action):
def __init__(self,
option_strings,
dest,
const,
const=None,
default=None,
required=False,
help=None,
Expand Down
19 changes: 19 additions & 0 deletions Lib/test/test_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,25 @@ class TestOptionalsActionAppendWithDefault(ParserTestCase):
]


class TestConstActionsMissingConstKwarg(ParserTestCase):
"""Tests that const gets default value of None when not provided"""

argument_signatures = [
Sig('-f', action='append_const'),
Sig('--foo', action='append_const'),
Sig('-b', action='store_const'),
Sig('--bar', action='store_const')
]
failures = ['-f v', '--foo=bar', '--foo bar']
successes = [
('', NS(f=None, foo=None, b=None, bar=None)),
('-f', NS(f=[None], foo=None, b=None, bar=None)),
('--foo', NS(f=None, foo=[None], b=None, bar=None)),
('-b', NS(f=None, foo=None, b=None, bar=None)),
('--bar', NS(f=None, foo=None, b=None, bar=None)),
]


class TestOptionalsActionAppendConst(ParserTestCase):
"""Tests the append_const action for an Optional"""

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
argparse actions store_const and append_const each receive a default value
of None when the ``const`` kwarg is not provided. Previously, this raised a
:exc:`TypeError`.