summaryrefslogtreecommitdiffstats
path: root/Lib/argparse.py
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-02-05 22:41:34 (GMT)
committerGitHub <noreply@github.com>2024-02-05 22:41:34 (GMT)
commitbb57ffdb38e9e8df8f9ea71f1430dbbe4bf2d3ac (patch)
treeab97e452b3e97ebc5375ba2229e5cf45707935f7 /Lib/argparse.py
parentc32bae52904723d99e1f98e2ef54570268d86467 (diff)
downloadcpython-bb57ffdb38e9e8df8f9ea71f1430dbbe4bf2d3ac.zip
cpython-bb57ffdb38e9e8df8f9ea71f1430dbbe4bf2d3ac.tar.gz
cpython-bb57ffdb38e9e8df8f9ea71f1430dbbe4bf2d3ac.tar.bz2
gh-83648: Support deprecation of options, arguments and subcommands in argparse (GH-114086)
Diffstat (limited to 'Lib/argparse.py')
-rw-r--r--Lib/argparse.py92
1 files changed, 68 insertions, 24 deletions
diff --git a/Lib/argparse.py b/Lib/argparse.py
index 2131d72..04ee3b1 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -843,7 +843,8 @@ class Action(_AttributeHolder):
choices=None,
required=False,
help=None,
- metavar=None):
+ metavar=None,
+ deprecated=False):
self.option_strings = option_strings
self.dest = dest
self.nargs = nargs
@@ -854,6 +855,7 @@ class Action(_AttributeHolder):
self.required = required
self.help = help
self.metavar = metavar
+ self.deprecated = deprecated
def _get_kwargs(self):
names = [
@@ -867,6 +869,7 @@ class Action(_AttributeHolder):
'required',
'help',
'metavar',
+ 'deprecated',
]
return [(name, getattr(self, name)) for name in names]
@@ -889,7 +892,8 @@ class BooleanOptionalAction(Action):
choices=_deprecated_default,
required=False,
help=None,
- metavar=_deprecated_default):
+ metavar=_deprecated_default,
+ deprecated=False):
_option_strings = []
for option_string in option_strings:
@@ -927,7 +931,8 @@ class BooleanOptionalAction(Action):
choices=choices,
required=required,
help=help,
- metavar=metavar)
+ metavar=metavar,
+ deprecated=deprecated)
def __call__(self, parser, namespace, values, option_string=None):
@@ -950,7 +955,8 @@ class _StoreAction(Action):
choices=None,
required=False,
help=None,
- metavar=None):
+ metavar=None,
+ deprecated=False):
if nargs == 0:
raise ValueError('nargs for store actions must be != 0; if you '
'have nothing to store, actions such as store '
@@ -967,7 +973,8 @@ class _StoreAction(Action):
choices=choices,
required=required,
help=help,
- metavar=metavar)
+ metavar=metavar,
+ deprecated=deprecated)
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values)
@@ -982,7 +989,8 @@ class _StoreConstAction(Action):
default=None,
required=False,
help=None,
- metavar=None):
+ metavar=None,
+ deprecated=False):
super(_StoreConstAction, self).__init__(
option_strings=option_strings,
dest=dest,
@@ -990,7 +998,8 @@ class _StoreConstAction(Action):
const=const,
default=default,
required=required,
- help=help)
+ help=help,
+ deprecated=deprecated)
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, self.const)
@@ -1003,14 +1012,16 @@ class _StoreTrueAction(_StoreConstAction):
dest,
default=False,
required=False,
- help=None):
+ help=None,
+ deprecated=False):
super(_StoreTrueAction, self).__init__(
option_strings=option_strings,
dest=dest,
const=True,
- default=default,
+ deprecated=deprecated,
required=required,
- help=help)
+ help=help,
+ default=default)
class _StoreFalseAction(_StoreConstAction):
@@ -1020,14 +1031,16 @@ class _StoreFalseAction(_StoreConstAction):
dest,
default=True,
required=False,
- help=None):
+ help=None,
+ deprecated=False):
super(_StoreFalseAction, self).__init__(
option_strings=option_strings,
dest=dest,
const=False,
default=default,
required=required,
- help=help)
+ help=help,
+ deprecated=deprecated)
class _AppendAction(Action):
@@ -1042,7 +1055,8 @@ class _AppendAction(Action):
choices=None,
required=False,
help=None,
- metavar=None):
+ metavar=None,
+ deprecated=False):
if nargs == 0:
raise ValueError('nargs for append actions must be != 0; if arg '
'strings are not supplying the value to append, '
@@ -1059,7 +1073,8 @@ class _AppendAction(Action):
choices=choices,
required=required,
help=help,
- metavar=metavar)
+ metavar=metavar,
+ deprecated=deprecated)
def __call__(self, parser, namespace, values, option_string=None):
items = getattr(namespace, self.dest, None)
@@ -1077,7 +1092,8 @@ class _AppendConstAction(Action):
default=None,
required=False,
help=None,
- metavar=None):
+ metavar=None,
+ deprecated=False):
super(_AppendConstAction, self).__init__(
option_strings=option_strings,
dest=dest,
@@ -1086,7 +1102,8 @@ class _AppendConstAction(Action):
default=default,
required=required,
help=help,
- metavar=metavar)
+ metavar=metavar,
+ deprecated=deprecated)
def __call__(self, parser, namespace, values, option_string=None):
items = getattr(namespace, self.dest, None)
@@ -1102,14 +1119,16 @@ class _CountAction(Action):
dest,
default=None,
required=False,
- help=None):
+ help=None,
+ deprecated=False):
super(_CountAction, self).__init__(
option_strings=option_strings,
dest=dest,
nargs=0,
default=default,
required=required,
- help=help)
+ help=help,
+ deprecated=deprecated)
def __call__(self, parser, namespace, values, option_string=None):
count = getattr(namespace, self.dest, None)
@@ -1124,13 +1143,15 @@ class _HelpAction(Action):
option_strings,
dest=SUPPRESS,
default=SUPPRESS,
- help=None):
+ help=None,
+ deprecated=False):
super(_HelpAction, self).__init__(
option_strings=option_strings,
dest=dest,
default=default,
nargs=0,
- help=help)
+ help=help,
+ deprecated=deprecated)
def __call__(self, parser, namespace, values, option_string=None):
parser.print_help()
@@ -1144,7 +1165,8 @@ class _VersionAction(Action):
version=None,
dest=SUPPRESS,
default=SUPPRESS,
- help="show program's version number and exit"):
+ help="show program's version number and exit",
+ deprecated=False):
super(_VersionAction, self).__init__(
option_strings=option_strings,
dest=dest,
@@ -1188,6 +1210,7 @@ class _SubParsersAction(Action):
self._parser_class = parser_class
self._name_parser_map = {}
self._choices_actions = []
+ self._deprecated = set()
super(_SubParsersAction, self).__init__(
option_strings=option_strings,
@@ -1198,7 +1221,7 @@ class _SubParsersAction(Action):
help=help,
metavar=metavar)
- def add_parser(self, name, **kwargs):
+ def add_parser(self, name, *, deprecated=False, **kwargs):
# set prog from the existing prefix
if kwargs.get('prog') is None:
kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
@@ -1226,6 +1249,10 @@ class _SubParsersAction(Action):
for alias in aliases:
self._name_parser_map[alias] = parser
+ if deprecated:
+ self._deprecated.add(name)
+ self._deprecated.update(aliases)
+
return parser
def _get_subactions(self):
@@ -1241,13 +1268,17 @@ class _SubParsersAction(Action):
# select the parser
try:
- parser = self._name_parser_map[parser_name]
+ subparser = self._name_parser_map[parser_name]
except KeyError:
args = {'parser_name': parser_name,
'choices': ', '.join(self._name_parser_map)}
msg = _('unknown parser %(parser_name)r (choices: %(choices)s)') % args
raise ArgumentError(self, msg)
+ if parser_name in self._deprecated:
+ parser._warning(_("command '%(parser_name)s' is deprecated") %
+ {'parser_name': parser_name})
+
# parse all the remaining options into the namespace
# store any unrecognized options on the object, so that the top
# level parser can decide what to do with them
@@ -1255,7 +1286,7 @@ class _SubParsersAction(Action):
# In case this subparser defines new defaults, we parse them
# in a new namespace object and then update the original
# namespace for the relevant parts.
- subnamespace, arg_strings = parser.parse_known_args(arg_strings, None)
+ subnamespace, arg_strings = subparser.parse_known_args(arg_strings, None)
for key, value in vars(subnamespace).items():
setattr(namespace, key, value)
@@ -1975,6 +2006,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# converts arg strings to the appropriate and then takes the action
seen_actions = set()
seen_non_default_actions = set()
+ warned = set()
def take_action(action, argument_strings, option_string=None):
seen_actions.add(action)
@@ -2070,6 +2102,10 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# the Optional's string args stopped
assert action_tuples
for action, args, option_string in action_tuples:
+ if action.deprecated and option_string not in warned:
+ self._warning(_("option '%(option)s' is deprecated") %
+ {'option': option_string})
+ warned.add(option_string)
take_action(action, args, option_string)
return stop
@@ -2089,6 +2125,10 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
for action, arg_count in zip(positionals, arg_counts):
args = arg_strings[start_index: start_index + arg_count]
start_index += arg_count
+ if args and action.deprecated and action.dest not in warned:
+ self._warning(_("argument '%(argument_name)s' is deprecated") %
+ {'argument_name': action.dest})
+ warned.add(action.dest)
take_action(action, args)
# slice off the Positionals that we just parsed and return the
@@ -2650,3 +2690,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
self.print_usage(_sys.stderr)
args = {'prog': self.prog, 'message': message}
self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
+
+ def _warning(self, message):
+ args = {'prog': self.prog, 'message': message}
+ self._print_message(_('%(prog)s: warning: %(message)s\n') % args, _sys.stderr)