Export to GitHub

argparse - issue #1

Using default values with the append action


Posted on Mar 27, 2009 by Grumpy Rabbit

[Originally submitted by risto.kankkunen@iki.fi to python-hosting.org tracker]

The default behavior for options with append action is not very convenient:

>>> import argparse >>> parser = argparse.ArgumentParser() >>> parser.add_argument("--foo", action='append') >>> parser.parse_args(('--foo=1', '--foo=2')) Namespace(foo=['1', '2']) >>> parser.parse_args(()) Namespace(foo=None)

You would expect to get zero or more items in a list for options having an append action. Now you get either None or one or more items in a list.

Giving a default value to fix this doesn't work:

>>> import argparse >>> parser = argparse.ArgumentParser() >>> parser.add_argument("--foo", action='append', default=[]) >>> parser.parse_args(()) Namespace(foo=[]) >>> parser.parse_args(('--foo=1', '--foo=2')) Namespace(foo=['1', '2']) >>> parser.parse_args(()) Namespace(foo=['1', '2']) >>> parser.parse_args(('--foo=1', '--foo=2')) Namespace(foo=['1', '2', '1', '2'])

This also applies if you want to have any other default value: if the default is mutable, the default gets mutated. If the default is immutable, you get an exception.

Comment #1

Posted on Mar 28, 2009 by Grumpy Rabbit

I'm curious what your use case is that requires calling parse_args more than once. Could you elaborate?

Comment #2

Posted on Apr 29, 2009 by Grumpy Rabbit

The use case is:

"I needed to parse the command line twice, because I wanted to combine options from the command line and from a configuration file: I parse the command line and check if there is a '--config=FILE' option. If there is, I parse the config file and call set_defaults() for each item there. This way I get the same error checking etc. for free. After this I need of course to re-parse the command line so that its options override the ones from the config file."

The fix, I believe should be to rewrite _AppendAction and _AppendConstAction to do something like:

items = _ensure_value(namespace, self.dest, []) + [values]
setattr(namespace, self.dest, items)

instead of the current call to append.

Comment #3

Posted on May 4, 2009 by Grumpy Rabbit

All append actions copy their destination list as of r21.

Comment #4

Posted on Oct 7, 2011 by Happy Camel

Not sure why this was marked as fixed. argparse 1.2.1 still has this issue.

Comment #5

Posted on Dec 15, 2011 by Grumpy Rabbit

The issue that was fixed was that if a default is supplied, it is copied so that multiple calls to parse_args work correctly.

I assume you're asking for the default for the "append" action to be an empty list? If so, please open a new issue for that, at the argparse bug tracker, which is the Python bug tracker: http://bugs.python.org/ Bugs reported to the Google Code tracker are likely to be lost.

Status: Fixed

Labels:
Type-Defect Priority-High