argparse ConfigureAction problem

Neal Becker ndbecker2 at gmail.com
Sat Mar 24 14:30:09 EDT 2012


I've been using arparse with ConfigureAction (which is shown below).  But, it 
doesn't play well with positional arguments.  For example:

./plot_stuff2.py --plot stuff1 stuff2
[...]
plot_stuff2.py: error: argument --plot/--with-plot/--enable-plot/--no-plot/--
without-plot/--disable-plot: invalid boolean value: 'stuff1'

Problem is --plot takes an optional argument, and so the positional arg is 
assumed to be the arg to --plot.  Not sure how to fix this.


Here is the parser code:

    parser = argparse.ArgumentParser()

[...]
    parser.add_argument ('--plot', action=ConfigureAction, default=False)
    parser.add_argument ('files', nargs='*')
    
    opt = parser.parse_args(cmdline[1:])

Here is ConfigureAction:

-----------------------------------------------------
import argparse
import re


def boolean(string):
    string = string.lower()
    if string in ['0', 'f', 'false', 'no', 'off']:
        return False
    elif string in ['1', 't', 'true', 'yes', 'on']:
        return True
    else:
        raise ValueError()


class ConfigureAction(argparse.Action):

    def __init__(self,
                 option_strings,
                 dest,
                 default=None,
                 required=False,
                 help=None,
                 metavar=None,
                 positive_prefixes=['--', '--with-', '--enable-'],
                 negative_prefixes=['--no-', '--without-', '--disable-']):
        strings = []
        self.positive_strings = set()
        self.negative_strings = set()
        for string in option_strings:
            assert re.match(r'--[A-z]+', string)
            suffix = string[2:]
            for positive_prefix in positive_prefixes:
                self.positive_strings.add(positive_prefix + suffix)
                strings.append(positive_prefix + suffix)
            for negative_prefix in negative_prefixes:
                self.negative_strings.add(negative_prefix + suffix)
                strings.append(negative_prefix + suffix)
        super(ConfigureAction, self).__init__(
            option_strings=strings,
            dest=dest,
            nargs='?',
            const=None,
            default=default,
            type=boolean,
            choices=None,
            required=required,
            help=help,
            metavar=metavar)

    def __call__(self, parser, namespace, value, option_string=None):
        if value is None:
            value = option_string in self.positive_strings
        elif option_string in self.negative_strings:
            value = not value
        setattr(namespace, self.dest, value)





More information about the Python-list mailing list