steven.beth...@gmail.com made a very nice module for me to enhance argparse 
called argparse_bool.py, which contains ConfigureAction.  This will allow a 
boolean value to be set very like the gnu configure style:

--foo
--with-foo
--without-foo
--no-foo
--foo=yes
--foo=no

I've been happily using it, and I think it would be of sufficient general 
interest to include it with the standard library.

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)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--fun', action=ConfigureAction)
    assert parser.parse_args([]).fun == None
    assert parser.parse_args(['--fun']).fun == True
    assert parser.parse_args(['--with-fun']).fun == True
    assert parser.parse_args(['--enable-fun']).fun == True
    assert parser.parse_args(['--no-fun']).fun == False
    assert parser.parse_args(['--without-fun']).fun == False
    assert parser.parse_args(['--disable-fun']).fun == False
    print parser.parse_args()

_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to