diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2024-02-05 22:41:34 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-05 22:41:34 (GMT) |
commit | bb57ffdb38e9e8df8f9ea71f1430dbbe4bf2d3ac (patch) | |
tree | ab97e452b3e97ebc5375ba2229e5cf45707935f7 /Lib/argparse.py | |
parent | c32bae52904723d99e1f98e2ef54570268d86467 (diff) | |
download | cpython-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.py | 92 |
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) |