[Python-checkins] gh-92248: Deprecate `type`, `choices`, `metavar` parameters of `argparse.BooleanOptionalAction` (#103678)

hugovk webhook-mailer at python.org
Fri May 19 12:45:04 EDT 2023


https://github.com/python/cpython/commit/27a7d5e1cd5b937d5f164fce572d442672f53065
commit: 27a7d5e1cd5b937d5f164fce572d442672f53065
branch: main
author: Nikita Sobolev <mail at sobolevn.me>
committer: hugovk <hugovk at users.noreply.github.com>
date: 2023-05-19T16:44:43Z
summary:

gh-92248: Deprecate `type`, `choices`, `metavar` parameters of `argparse.BooleanOptionalAction` (#103678)

Co-authored-by: Kirill <80244920+Eclips4 at users.noreply.github.com>
Co-authored-by: Hugo van Kemenade <hugovk at users.noreply.github.com>
Co-authored-by: Oleg Iarygin <oleg at arhadthedev.net>

files:
A Misc/NEWS.d/next/Library/2023-04-22-12-30-10.gh-issue-92248.NcVTKR.rst
M Doc/whatsnew/3.12.rst
M Lib/argparse.py
M Lib/test/test_argparse.py

diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 25f0a4c3ca26..8a0a59ba7301 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -870,6 +870,11 @@ Pending Removal in Python 3.14
 * The *onerror* argument of :func:`shutil.rmtree` is deprecated in 3.12,
   and will be removed in 3.14.
 
+* The *type*, *choices*, and *metavar* parameters
+  of :class:`!argparse.BooleanOptionalAction` are deprecated
+  and will be removed in 3.14.
+  (Contributed by Nikita Sobolev in :gh:`92248`.)
+
 * :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader`
   now raise :exc:`DeprecationWarning`;
   use :func:`importlib.util.find_spec` instead.
diff --git a/Lib/argparse.py b/Lib/argparse.py
index f5f44ff02c0d..543d9944f9ed 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -883,16 +883,19 @@ def __call__(self, parser, namespace, values, option_string=None):
         raise NotImplementedError(_('.__call__() not defined'))
 
 
+# FIXME: remove together with `BooleanOptionalAction` deprecated arguments.
+_deprecated_default = object()
+
 class BooleanOptionalAction(Action):
     def __init__(self,
                  option_strings,
                  dest,
                  default=None,
-                 type=None,
-                 choices=None,
+                 type=_deprecated_default,
+                 choices=_deprecated_default,
                  required=False,
                  help=None,
-                 metavar=None):
+                 metavar=_deprecated_default):
 
         _option_strings = []
         for option_string in option_strings:
@@ -902,6 +905,24 @@ def __init__(self,
                 option_string = '--no-' + option_string[2:]
                 _option_strings.append(option_string)
 
+        # We need `_deprecated` special value to ban explicit arguments that
+        # match default value. Like:
+        #   parser.add_argument('-f', action=BooleanOptionalAction, type=int)
+        for field_name in ('type', 'choices', 'metavar'):
+            if locals()[field_name] is not _deprecated_default:
+                warnings._deprecated(
+                    field_name,
+                    "{name!r} is deprecated as of Python 3.12 and will be "
+                    "removed in Python {remove}.",
+                    remove=(3, 14))
+
+        if type is _deprecated_default:
+            type = None
+        if choices is _deprecated_default:
+            choices = None
+        if metavar is _deprecated_default:
+            metavar = None
+
         super().__init__(
             option_strings=_option_strings,
             dest=dest,
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 0659d244d356..3a62a16cee31 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -765,6 +765,49 @@ def test_const(self):
 
         self.assertIn("got an unexpected keyword argument 'const'", str(cm.exception))
 
+    def test_deprecated_init_kw(self):
+        # See gh-92248
+        parser = argparse.ArgumentParser()
+
+        with self.assertWarns(DeprecationWarning):
+            parser.add_argument(
+                '-a',
+                action=argparse.BooleanOptionalAction,
+                type=None,
+            )
+        with self.assertWarns(DeprecationWarning):
+            parser.add_argument(
+                '-b',
+                action=argparse.BooleanOptionalAction,
+                type=bool,
+            )
+
+        with self.assertWarns(DeprecationWarning):
+            parser.add_argument(
+                '-c',
+                action=argparse.BooleanOptionalAction,
+                metavar=None,
+            )
+        with self.assertWarns(DeprecationWarning):
+            parser.add_argument(
+                '-d',
+                action=argparse.BooleanOptionalAction,
+                metavar='d',
+            )
+
+        with self.assertWarns(DeprecationWarning):
+            parser.add_argument(
+                '-e',
+                action=argparse.BooleanOptionalAction,
+                choices=None,
+            )
+        with self.assertWarns(DeprecationWarning):
+            parser.add_argument(
+                '-f',
+                action=argparse.BooleanOptionalAction,
+                choices=(),
+            )
+
 class TestBooleanOptionalActionRequired(ParserTestCase):
     """Tests BooleanOptionalAction required"""
 
diff --git a/Misc/NEWS.d/next/Library/2023-04-22-12-30-10.gh-issue-92248.NcVTKR.rst b/Misc/NEWS.d/next/Library/2023-04-22-12-30-10.gh-issue-92248.NcVTKR.rst
new file mode 100644
index 000000000000..d4a02d829419
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-04-22-12-30-10.gh-issue-92248.NcVTKR.rst
@@ -0,0 +1,2 @@
+Deprecate ``type``, ``choices``, and ``metavar`` parameters of
+``argparse.BooleanOptionalAction``.



More information about the Python-checkins mailing list