While using Python's add_argument in argparse, how can I throw an exception if a particular deprecated flag is called?
Asked Answered
M

2

6

Basically imagine that I have argparser that has multiple arguments. I have a particular function definition that looks like this:

    def add_to_parser(self, parser):
        group = parser.add_argument_group('')
        group.add_argument( '--deprecateThis', action='throw exception', help='Stop using this. this is deprecated')

Whether I can try and create that action to throw an exception and stop the code or if I can wrap it to check for the deprecateThis flag and then throw an exception, I'd like to know how to do it and which is best! Thanks.

Malposition answered 16/11, 2016 at 22:22 Comment(4)
You could provide a type function that throws an error if anything is supplied to it. Or yes, just check after the parsing if there's anything in that argument.Jemison
but what if I want to have "action=throwexception" or something? Where would I be providing the type function to do so? Thanks for the fast response!Malposition
No, there are predefined actions. Demo of using type: https://mcmap.net/q/156402/-specify-date-format-for-python-argparse-input-argumentsJemison
That works! Thanks a lot @Jemison :) If you wanna answer it, i'll give you the check!Malposition
H
4

From https://docs.python.org/3.13/library/argparse.html#deprecated:

During a project’s lifetime, some arguments may need to be removed from the command line. Before removing them, you should inform your users that the arguments are deprecated and will be removed.

So your program should not stop, but instead it should show a warning.

Starting from python 3.13, you can use a parameter deprecated in methods add_argument() and add_parser(), which allows to deprecate command-line options, positional arguments and subcommands.

In this case, all you need to do is:

group.add_argument( '--deprecateThis', deprecated=True)
Humbert answered 28/2, 2024 at 11:9 Comment(0)
P
3

Here's what I came up with:

You can register custom actions for your arguments, I registered one to print out a deprecation warning and remove the item from the resulting namespace:

class DeprecateAction(argparse.Action):
    def __init__(self, *args, **kwargs):
        self.call_count = 0
        if 'help' in kwargs:
            kwargs['help'] = f'[DEPRECATED] {kwargs["help"]}'
        super().__init__(*args, **kwargs)


    def __call__(self, parser, namespace, values, option_string=None):
        if self.call_count == 0:
            sys.stderr.write(f"The option `{option_string}` is deprecated. It will be ignored.\n")
            sys.stderr.write(self.help + '\n')
            delattr(namespace, self.dest)
        self.call_count += 1


if __name__ == "__main__":
    my_parser = ArgumentParser('this is the description')
    my_parser.register('action', 'ignore', DeprecateAction)
    my_parser.add_argument(
        '-f', '--foo', 
        help="This argument is deprecated", 
        action='ignore')

    args = my_parser.parse_args()
    # print(args.foo)  # <- would throw an exception
Phenomena answered 4/9, 2021 at 5:31 Comment(1)
Note, register() is an undocumented argparse method, but it is not hidden.Efface

© 2022 - 2025 — McMap. All rights reserved.