1

I have a Python script that can deploy some software in three different environments, let's call them development, testing and production. In order to select which environment the script should work with, I want to use mutually exclusive flags, like so:

./deploy.py --development
./deploy.py --testing
./deploy.py --production

So far I have this:

parser = argparse.ArgumentParser(description="Manage deployment")

group = parser.add_mutually_exclusive_group()

group.add_argument("-d", "--development", action='store_true', required=False)
group.add_argument("-t", "--testing", action='store_true', required=False)
group.add_argument("-p", "--production", action='store_true', required=False)

args = parser.parse_args()

Thing is, I want to have the environment in a single variable, so I can easily check it, instead of having to manually check args.development, args.testing and args.production.

Is there a way of having a common variable that the three arguments could write to so I could do something like args.environment?

José Tomás Tocino
  • 9,873
  • 5
  • 44
  • 78

2 Answers2

2

Instead of using action='store_true', you can use action='store_const', assign an individual const value for each argument and the dest option of add_argument, so that all the arguments in the mutually exclusive group have the same destination in the object returned by parse_args.

parser = argparse.ArgumentParser(description="Manage deployment")

group = parser.add_mutually_exclusive_group()

group.add_argument("-d", "--development", action='store_const', dest='environment', const='development', required=False)
group.add_argument("-t", "--testing",     action='store_const', dest='environment', const='testing',     required=False)
group.add_argument("-p", "--production",  action='store_const', dest='environment', const='production',  required=False)

args = parser.parse_args()

print(args)

The output is:

$ ./test_args.py --production
Namespace(environment='production')
José Tomás Tocino
  • 9,873
  • 5
  • 44
  • 78
  • Maybe useful to add: You can also set a default value which is used if none of the flags is set: `group.set_defaults(environment="default value")` – luator Nov 18 '22 at 09:27
1

Instead of 3 arguments, you can just use one with choices:

parser = argparse.ArgumentParser(description="Manage deployment")

parser.add_argument("environment", choices=['development', 'testing', 'production'])

args = parser.parse_args()
print(args)

Examples:

>>> test_args.py
usage: concept.py [-h] {development,testing,production}
test_args.py: error: the following arguments are required: environment

>>> test_args.py testing
Namespace(environment='testing')
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • Thanks, but actually I cannot, because I have other positional arguments, that's why I stated I wanted to use flags. – José Tomás Tocino Sep 23 '20 at 12:07
  • I thought that this might be a problem, although not necessarily? Why does it bother to have other positionals? Anyway, in that case your own solution seems pretty good for it :) – Tomerikoo Sep 23 '20 at 12:14