[docs] [issue16399] argparse: append action with default list adds to list instead of overriding

Yclept Nemo report at bugs.python.org
Wed Aug 6 21:30:21 CEST 2014


Yclept Nemo added the comment:

Well that won't work. Example:

import argparse

class TestAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        print("default: {}({})\tdest: {}({})".format(self.default, type(self.default), getattr(namespace, self.dest), type(getattr(namespace, self.dest))))
        if getattr(namespace, self.dest) is self.default:
            print("Replacing with: ", values)
            setattr(namespace, self.dest, values)
        # extra logical code not necessary for testcase

parser = argparse.ArgumentParser()

parser.add_argument\
        ( "-o", "--output"
        , type=int
        , action=TestAction
        , default=42
        )

args = parser.parse_args()

$ ./argparse_test -o 42 -o 100
default: 42(<class 'int'>)      dest: 42(<class 'int'>)
Replacing with:  42
default: 42(<class 'int'>)      dest: 42(<class 'int'>)
Replacing with:  100
100

Use this approach:
class ExtendAction(argparse.Action):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if not isinstance(self.default, collections.abc.Iterable):
            self.default = [self.default]
        self.reset_dest = False
    def __call__(self, parser, namespace, values, option_string=None):
        if not self.reset_dest:
            setattr(namespace, self.dest, [])
            self.reset_dest = True
        getattr(namespace, self.dest).extend(values)

Anyway, this should be properly documented...

----------
nosy: +Yclept.Nemo

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue16399>
_______________________________________


More information about the docs mailing list