Argparse: "Default" interacts incorrectly/non-intuitively with action='append' and action='extend' · Issue #110131 · python/cpython · GitHub
Skip to content

Argparse: "Default" interacts incorrectly/non-intuitively with action='append' and action='extend' #110131

Description

@rhetzler

Bug report

Bug description:

The documentation for default claims:

The default keyword argument of add_argument(), whose value defaults to None, specifies what value should be used if the command-line argument is not present
which (implicitly) sets the expectation that the default is not used if the command-line argument is present

in it's defense, the strange behaviour is documented in append but not extend

If the default value is non-empty, the default elements will be present in the parsed value for the option, with any values from the command line appended after those default values

However, this behaviour is non-intuitive. The fact that the values will be prepended to the end-user's input is not obvious, furthermore, the end-user is unable to specify a set of parameters that don't contain undesired default values.

    DEFAULT_SET=['a','b','c','d']
    parser = argparse.ArgumentParser()
    parser.add_argument('--items',nargs='+',action='extend',dest='items',choices=DEFAULT_SET,default=DEFAULT_SET)
    args = parser.parse_args()

    print(args.items)

$ python3 example.py --items a --items b c # expected: items will contain 'a', 'b', and 'c'
['a', 'b', 'c', 'd', 'a', 'b', 'c']

Now it's fair to say that there's a workaround:

    parser.add_argument('--items',nargs='+',action='extend',dest='items',choices=DEFAULT_SET,default=None)
    args = parser.parse_args()
    if args.items == None:
        args.items = DEFAULT_SET 

however, isn't this the pattern that default= aims to eliminate/alleviate in the first place?

If the purpose of DEFAULT is to supply a value in the absense of user input, the fact that it supplies a value even when the user supplies input is an undesired side effect and not really default behaviour.

If the code needs to always be processing a set of values regardless of user input, then that really should be clearly stated in the code/logic, rather than a side effect of the input parsing

    do_something(DEFAULT_SET + args.items) # no ambiguity

hope this makes sense. thank you!

CPython versions tested on:

3.8

Operating systems tested on:

macOS

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.12only security fixes3.13bugs and security fixes3.14bugs and security fixesdocsDocumentation in the Doc dirstdlibStandard Library Python modules in the Lib/ directory

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions