From 2d0ff8ec553392724a0a890d41b2d62d84454755 Mon Sep 17 00:00:00 2001 From: Braden Groom Date: Sat, 27 Oct 2018 17:14:26 -0700 Subject: [PATCH] Deprecate using add_parser() to overwrite an existing subparser --- Doc/whatsnew/3.8.rst | 4 ++++ Lib/argparse.py | 14 ++++++++++++++ Lib/test/test_argparse.py | 12 ++++++++++++ .../2018-10-27-17-13-25.bpo-14856.F4DJr3.rst | 2 ++ 4 files changed, 32 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2018-10-27-17-13-25.bpo-14856.F4DJr3.rst diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 05b7d235cee800..cad287064ded31 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -312,6 +312,10 @@ Deprecated (Contributed by Serhiy Storchaka in :issue:`33710`.) +* Using :meth:`~argparser._SubParsersAction.add_parser` to overwrite an existing + subparser is deprecated and will be prohibited in Python 3.9. + (Contributed by Braden Groom in :issue:`14856`.) + Removed ======= diff --git a/Lib/argparse.py b/Lib/argparse.py index 798766f6c4086a..a696d47f0ab4f1 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1097,6 +1097,20 @@ def __init__(self, metavar=metavar) def add_parser(self, name, **kwargs): + import warnings + if name in self._name_parser_map: + warnings.warn('using add_parser() to overwrite an existing ' + 'subparser is deprecated, use set_parser() instead', + DeprecationWarning, 2) + aliases = kwargs.get('aliases', []) + for alias in aliases: + if alias in self._name_parser_map: + warnings.warn('using add_parser() to overwrite an existing ' + 'subparser is deprecated, use set_parser() instead', + DeprecationWarning, 2) + return self.set_parser(name, **kwargs) + + def set_parser(self, name, **kwargs): # set prog from the existing prefix if kwargs.get('prog') is None: kwargs['prog'] = '%s %s' % (self._prog_prefix, name) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index c0c7cb05940ba9..513e4b2422eae1 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -2149,6 +2149,18 @@ def test_alias_help(self): 3 3 help """)) + def test_warn_already_defined_subparser(self): + parser = ErrorRaisingArgumentParser() + subparsers = parser.add_subparsers() + subparsers.add_parser('foo') + self.assertWarns(DeprecationWarning, subparsers.add_parser, 'foo') + + def test_warn_already_defined_alias(self): + parser = ErrorRaisingArgumentParser() + subparsers = parser.add_subparsers() + subparsers.add_parser('foo') + self.assertWarns(DeprecationWarning, subparsers.add_parser, 'bar', aliases=['foo']) + # ============ # Groups tests # ============ diff --git a/Misc/NEWS.d/next/Library/2018-10-27-17-13-25.bpo-14856.F4DJr3.rst b/Misc/NEWS.d/next/Library/2018-10-27-17-13-25.bpo-14856.F4DJr3.rst new file mode 100644 index 00000000000000..21ae3f6896c7e5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-10-27-17-13-25.bpo-14856.F4DJr3.rst @@ -0,0 +1,2 @@ +Deprecate using add_parser() to overwrite an existing subparser. +Patch by Braden Groom