Argparse: add_argument with action=append appends to default

J

John O'Hagan

I find this surprising:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--test', action='append', default=['default']) [...]
parser.parse_args(['--test', 'arg'])
Namespace(test=['default', 'arg'])

As an argument is provided, I didn't expect to see the default in there as
well. From the argparse docs: "the default value is used when the option
string was not present at the command line". While it doesn't say "_only_
when...", that's what I would have expected.

Is there a reason for this behaviour? Is there a way to do what I want, to get
a list of appended options _or_ a default list (apart from setting defaults
outside the parser, a good way to lose track of things)?

Thanks,

John
 
P

Peter Otten

John said:
I find this surprising:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--test', action='append', default=['default']) [...]
parser.parse_args(['--test', 'arg'])
Namespace(test=['default', 'arg'])

As an argument is provided, I didn't expect to see the default in there as
well. From the argparse docs: "the default value is used when the option
string was not present at the command line". While it doesn't say "_only_
when...", that's what I would have expected.

Is there a reason for this behaviour? Is there a way to do what I want, to
get a list of appended options _or_ a default list (apart from setting
defaults outside the parser, a good way to lose track of things)?

You could either tweak the default value or the action:

$ cat append.py
import argparse

class DefaultList(list):
def __copy__(self):
return []

if __name__ == "__main__":
p = argparse.ArgumentParser()
p.add_argument("-t", "--test", action="append",
default=DefaultList(["default"]))

print p.parse_args()
$ python append.py -t one -t two
Namespace(test=['one', 'two'])
$ python append.py -t one
Namespace(test=['one'])
$ python append.py
Namespace(test=['default'])


$ cat append1.py
import argparse

class DefaultAppend(argparse._AppendAction):
def __call__(self, parser, namespace, values, option_string=None):
items = argparse._copy.copy(argparse._ensure_value(namespace,
self.dest, []))
try:
self._not_first
except AttributeError:
self._not_first = True
del items[:]
items.append(values)
setattr(namespace, self.dest, items)

if __name__ == "__main__":
p = argparse.ArgumentParser()
p.add_argument("-t", "--test", action=DefaultAppend,
default=["default"])
print p.parse_args()
$ python append1.py -t one -t two
Namespace(test=['one', 'two'])
$ python append1.py -t one
Namespace(test=['one'])
$ python append1.py
Namespace(test=['default'])

Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,708
Latest member
SherleneF1

Latest Threads

Top