Skip to content

argparse boolean type bug #83348

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
TrentonBricken mannequin opened this issue Dec 30, 2019 · 7 comments
Closed

argparse boolean type bug #83348

TrentonBricken mannequin opened this issue Dec 30, 2019 · 7 comments
Labels
3.7 (EOL) end of life type-bug An unexpected behavior, bug, or error

Comments

@TrentonBricken
Copy link
Mannequin

TrentonBricken mannequin commented Dec 30, 2019

BPO 39167
Nosy @rhettinger, @mdickinson, @tirkarthi
Superseder
  • bpo-37564: ArgumentParser should support bool type according to truth values
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2019-12-31.01:26:28.270>
    created_at = <Date 2019-12-30.16:18:30.908>
    labels = ['type-bug', '3.7']
    title = 'argparse boolean type bug'
    updated_at = <Date 2019-12-31.12:27:25.287>
    user = 'https://bugs.python.org/TrentonBricken'

    bugs.python.org fields:

    activity = <Date 2019-12-31.12:27:25.287>
    actor = 'Trenton Bricken'
    assignee = 'none'
    closed = True
    closed_date = <Date 2019-12-31.01:26:28.270>
    closer = 'josh.r'
    components = []
    creation = <Date 2019-12-30.16:18:30.908>
    creator = 'Trenton Bricken'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 39167
    keywords = []
    message_count = 7.0
    messages = ['359045', '359047', '359048', '359051', '359054', '359058', '359113']
    nosy_count = 5.0
    nosy_names = ['rhettinger', 'mark.dickinson', 'paul.j3', 'xtreak', 'Trenton Bricken']
    pr_nums = []
    priority = 'normal'
    resolution = 'duplicate'
    stage = 'resolved'
    status = 'closed'
    superseder = '37564'
    type = 'behavior'
    url = 'https://bugs.python.org/issue39167'
    versions = ['Python 3.7']

    @TrentonBricken
    Copy link
    Mannequin Author

    TrentonBricken mannequin commented Dec 30, 2019

    This is a bug with argparse.

    Say I have:

    parser.add_argument('--verbose', type=bool, action='store', nargs='+',
                            default = [False],
                            help='turns on verbosity')

    If in the command line I have "--verbose False' the default will then evaluate to True and return the value "True" rather than the value of "False" that I tried to set it to!

    When a developer has lots of arguments to pass in, they may not remember if an argument defaults to False or True. Setting the value to False and having it then return True is very confusing and should not occur.

    Right now I have a work-around where I have a new type=buildBool where:

    def buildBool(arg):
       return bool(arg)

    and do:

    parser.add_argument('--verbose', type=buildBool, action='store', nargs='+',
                            default = ['False'],
                            help='turns on verbosity')

    but this means I have to have this type and have my default value be a string which is suboptimal and this bug remains a trap for other developers.

    @TrentonBricken TrentonBricken mannequin added 3.7 (EOL) end of life type-bug An unexpected behavior, bug, or error labels Dec 30, 2019
    @TrentonBricken
    Copy link
    Mannequin Author

    TrentonBricken mannequin commented Dec 30, 2019

    Update:

    I was being dumb before, the problem still remains but my work around previously was wrong. This is the new workaround:

    def buildBool(arg):
        if arg == 'False':
            return False
        else:
            return True

    @tirkarthi
    Copy link
    Member

    It seems like this is a common problem : https://stackoverflow.com/questions/15008758/parsing-boolean-values-with-argparse . I guess you want to store verbose=True when --verbose is passed and verbose=False when --verbose is not passed where store_true might help.

    @TrentonBricken
    Copy link
    Mannequin Author

    TrentonBricken mannequin commented Dec 30, 2019

    Thank you for your quick and helpful reply.

    The problem with your solution is twofold:

    1. it adds some cognitive load in needing to remember whether or not the flag defaults to True or False and thus whether or not you need to add it. It is easier for me to have everything as a flag with a value that follows.
    2. More importantly, I am using argparse for trying lots of different combinations of inputs to a function so I pass them in as a list and then permute the possible values for each input.

    For example: --flag1 a b
    --flag2 c d

    I want to then run a command with the parameter combinations:
    a, c; a, d; b, c; b, d;

    And I don't think store_true store_false would allow me to pass in having combinations of True and False like --flag True False would.

    I am fine now with my current work around, but was very confused for some time why my flag would be true when I set it to false. And think this is a counterintuitive pitfall other developers can fall into.

    @paulj3
    Copy link
    Mannequin

    paulj3 mannequin commented Dec 30, 2019

    Despite the name, the 'type' parameter specifies a function, not a Python class.

    The only string that produces False is the empty one: bool(''). So 'type=bool' is valid Python, even if it isn't useful.

    With nargs='+' there's no problem with providing strings like 'False', 'true', 'no', 'oui', 'niet', but if you want to convert those to boolean True/False values, you need to write your own 'type' function.

    There was a recent bug/issue that proposed providing such a function (or importing it from another module), and shadowing the existing 'bool' function, but that has been rejected (I think). It isn't really needed, and the proposed solution was too language specific.

    Seems to me that expecting your user to provide an open ended list of 'True False False True' strings would be rather confusing, or at least require a complicated 'help' string. In any case it's not a common enough case to require any changes to the core argparse functionality.

    In sum, it isn't clear what the bug is, or what patch you expect. This sounds more like a StackOverflow question, than a bug report.

    @paulj3
    Copy link
    Mannequin

    paulj3 mannequin commented Dec 30, 2019

    The rejected boolean type proposal:

    https://bugs.python.org/issue37564

    @MojoVampire MojoVampire mannequin closed this as completed Dec 31, 2019
    @MojoVampire MojoVampire mannequin closed this as completed Dec 31, 2019
    @TrentonBricken
    Copy link
    Mannequin Author

    TrentonBricken mannequin commented Dec 31, 2019

    Thanks for all of these replies.

    The functionality is that the user adds --flag True False and then all of the other parameters are run with True. And then again with False.

    I thought this was a bug because of the confusing type=bool behavior. But it certainly isn't a big deal and it seems like you are already aware of it.

    Thanks for all of your open source contributions and help.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.7 (EOL) end of life type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    1 participant