Home > other >  Disable argparse arguments from being overwritten
Disable argparse arguments from being overwritten

Time:03-21

I have a legacy Python application which uses some options in its CLI, using argparse, like:

parser = argparse.ArgumentParser()
parser.add_argument('-f', default='foo')

Now I need to remove this option, since now its value cannot be overwritten by users but it has to assume its default value (say 'foo' in the example). Is there a way to keep the option but prevent it to show up and be overwritten by users (so that I can keep the rest of the code as it is)?

CodePudding user response:

I think it doesn't make sense for the argparse module to provide this as a standard option, but there are several easy ways to achieve what you want.

The most obvious way is to just overwrite the value after having called parse_args() (as already mentioned in comments and in another answer):

args.f = 'foo'

However, the user may not be aware that the option is not supported anymore and that the application is now assuming the value "foo". Depending on the use case, it might be better to warn the user about this. The argparse module has several options to do this.

Another possibility is to use an Action class to do a little magic. For example, you could print a warning if the user provided an option that is not supported anymore, or even use the built-in error handling.

import argparse

class FooAction(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        if values != 'foo':
            print('Warning: option `-f` has been removed, assuming `-f foo` now')
            # Or use the built-in error handling like this:
            # parser.error('Option "-f" is not supported anymore.')

        # You could override the argument value like this:
        # setattr(namespace, self.dest, 'foo')

parser = argparse.ArgumentParser()
parser.add_argument('-f', default='foo', action=FooAction)
args = parser.parse_args()
print('option=%s' % args.f)

You could also just limit the choices to only "foo" and let argparse create an error for other values:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-f', default='foo', choices=['foo'])
args = parser.parse_args()
print('option=%s' % args.f)

Calling python test.py -f bar would then result in:

usage: test.py [-h] [-f {foo}]
test.py: error: argument -f: invalid choice: 'bar' (choose from 'foo')

CodePudding user response:

Yes you can do that. After the parser is parsed (args = parser.parse_args()) it is a NameSpace so you can do this:

parser = argparse.ArgumentParser()
args = parser.parse_args()
args.foo = 'foo value'
print(args)
>>> Namespace(OTHER_OPTIONS, foo='foo value')

I assumed that you wanted to add test to your parser, so your original code will still work, but you do not want it as an option for the user.

  • Related