1

When I run my python code with -rm False I still see _REMOVE_ADS = True.

How can I fix this?

parser.add_argument(
    "-rm",
    "--remove_ads",
    type=bool,
    required=False,
    default=False,
    help="Should remove disapproved ads. Default: false",
)
# TODO: Fix booleans
args = parser.parse_args()
_REMOVE_ADS = args.remove_ads
print(_REMOVE_ADS)
Elad Benda
  • 35,076
  • 87
  • 265
  • 471
  • The `argparse` reference, warns, under the `type` header, **The bool() function is not recommended as a type converter. All it does is convert empty strings to False and non-empty strings to True. This is usually not what is desired.** – hpaulj Sep 10 '21 at 03:55

1 Answers1

2

This is because they are parsed as strings and any non-empty string is considered True by bool:

>>> bool("False")
True

To fix it, use a different type instead of type=bool, for Python < 3.10 there is a standard lib option which can be used:

from distutils.util import strtobool

You can register this type with a name on a parser instance:

from distutils.util import strtobool

parser = ArgumentParser(...)
parser.register('type', 'boolean', strtobool)
parser.add_argument('-rm', type='boolean')

Alternatively, just make this option into a flag so it doesn't need to accept an argument at all, although note that this does change your CLI usage syntax:

parser.add_argument(
    "-rm", "--remove-ads",
    action="store_true",
    help="Should remove disapproved ads",
)

In Python 3.10 the distutils module has been deprecated. The Migration Advice section of PEP-632 says there is no replacement for the strtobool function and you will need to re-implement the functionality yourself, but that should be easy enough (tweak as necessary):

def strtobool(val): 
    if val.lower().startswith("t"): 
        return True 
    elif val.lower().startswith("f"): 
        return False 
    raise argparse.ArgumentTypeError("invalid boolean value: {!r}".format(val)) 
wim
  • 338,267
  • 99
  • 616
  • 750
  • `just make it a flag so it doesn't ` how do I check that flag was used? – Elad Benda Sep 09 '21 at 18:58
  • If the flag was used, `args.remove_ads` will be `True`. If the flag was not provided, `args.remove_ads` will be `False`. And, in either case, `args.remove_ads` will _exist_ in the args namespace. – wim Sep 09 '21 at 19:00