[Originally submitted by ndbecker2@gmail.com to the python-hosting.org tracker]
2 things I'd like to see:
--option=True/False/1/0
to set the value of a boolean option- automatically add
--no-option
to set the value to false
Comment #1
Posted on Mar 28, 2009 by Grumpy Rabbit(No comment was entered for this change.)
Comment #2
Posted on Mar 28, 2009 by Grumpy Rabbit(No comment was entered for this change.)
Comment #3
Posted on Mar 28, 2009 by Grumpy RabbitI haven't yet decided whether this deserves to be added as part of argparse or just as a recipe somewhere. For reference though, here is some code that achieves this::
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, required=False, help=None, metavar=None): strings = [] self.positive_strings = set() self.negative_strings = set() for string in option_strings: assert string.startswith('--enable') or string.startswith('--with') strings.append(string) self.positive_strings.add(string) neg_string = string.replace('--enable', '--disable') neg_string = neg_string.replace('--with', '--without') strings.append(neg_string) self.negative_strings.add(neg_string) super(ConfigureAction, self).init( option_strings=strings, dest=dest, nargs='?', const=None, default=None, 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)
Comment #4
Posted on Mar 30, 2009 by Swift BearHow is this used?
Comment #5
Posted on Mar 30, 2009 by Grumpy Rabbitparser = argparse.ArgumentParser() parser.add_argument('--with-fun', action=ConfigureAction) parser.parse_args(['--with-fun']) Namespace(with_fun=True) parser.parse_args(['--without-fun']) Namespace(with_fun=False)
Comment #6
Posted on Jun 24, 2009 by Grumpy Rabbitimport 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()
Comment #7
Posted on Jul 14, 2009 by Swift BearIsn't that regex too restictive? assert re.match(r'--[A-z]+', string) How about [0-9]? How about '-_'?
Comment #8
Posted on Jul 21, 2009 by Grumpy RabbitYeah, probably checking for r'--\w' would be fine. Unless you were suggesting that it's valid to have a configure switch like -----foo?
Comment #9
Posted on Jul 21, 2009 by Swift BearNo, I was thinking of --with-some-function
Comment #10
Posted on Jul 21, 2009 by Grumpy RabbitThat would have worked already - re.match is just checking the start of the string, and --with-some-function begins with --[A-z].
Comment #11
Posted on Oct 8, 2009 by Swift BearAny way to make it interoperate with short options also?
parser.add_argument ('-l', '--limit', action=ConfigureAction, default=True) Traceback (most recent call last): File "test_agc.py", line 23, in parser.add_argument ('-l', '--limit', action=ConfigureAction, default=True) File "/usr/lib/python2.6/site-packages/argparse-1.0.1-py2.6.egg/argparse.py", line 1264, in add_argument action = action_class(**kwargs) File "/home/nbecker/scma-ldpc-fixed-scram-bpsk/test/argparse_bool.py", line 30, in init assert re.match(r'--[A-z]+', string) AssertionError
Comment #12
Posted on Oct 8, 2009 by Grumpy RabbitWhat behavior do you want from short options? Should that add "--no-l", etc.? Or what?
Comment #13
Posted on May 24, 2010 by Grumpy RabbitMoved to Python issue tracker: http://bugs.python.org/issue8537
Status: Duplicate
Labels:
Type-Enhancement
Priority-Medium