Reputation: 9540
I am trying to make a build script like this:
import glob
import os
import subprocess
import re
import argparse
import shutil
def create_parser():
parser = argparse.ArgumentParser(description='Build project')
parser.add_argument('--clean_logs', type=bool, default=True,
help='If true, old debug logs will be deleted.')
parser.add_argument('--run', type=bool, default=True,
help="If true, executable will run after compilation.")
parser.add_argument('--clean_build', type=bool, default=False,
help="If true, all generated files will be deleted and the"
" directory will be reset to a pristine condition.")
return parser.parse_args()
def main():
parser = create_parser()
print(parser)
However no matter how I try to pass the argument I only get the default values. I always get Namespace(clean_build=False, clean_logs=True, run=True)
.
I have tried:
python3 build.py --run False
python3 build.py --run=FALSE
python3 build.py --run FALSE
python3 build.py --run=False
python3 build.py --run false
python3 build.py --run 'False'
It's always the same thing. What am I missing?
Upvotes: 12
Views: 15818
Reputation: 10728
Argument run
is initialized to True
even that you pass --run False
Below code based on this great answer is workaround around this issue:
import argparse
def str2bool(v):
if isinstance(v, bool):
return v
if v.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
raise argparse.ArgumentTypeError('Boolean value expected.')
def main():
ap = argparse.ArgumentParser()
# List of args
ap.add_argument('--foo', type=str2bool, help='Some helpful text')
# Importable object
args = ap.parse_args()
print(args.foo)
if __name__ == '__main__':
main()
Upvotes: 6
Reputation: 480
You are misunderstanding how the argparse
understands the boolean arguments.
Basically you should use action='store_true'
or action='store_false'
instead of the default value, with the understanding that not specifying the argument will give you the opposite of the action, e.g.
parser.add_argument('-x', type=bool, action='store_true')
will cause:
python3 command -x
to have x
set to True
and
python3 command
to have x
set to False
.
While action=store_false
will do the opposite.
Setting bool
as type does not behave as you expect and this is a known issue.
The reason for the current behavior is that type
is expected to be a callable which is used as argument = type(argument)
. bool('False')
evaluates to True
, so you need to set a different type
for the behavior you expect to happen.
Upvotes: 21