deprecated=False):
_option_strings = []
+ neg_option_strings = []
for option_string in option_strings:
_option_strings.append(option_string)
- if option_string.startswith('--'):
- if option_string.startswith('--no-'):
+ if len(option_string) > 2 and option_string[0] == option_string[1]:
+ # two-dash long option: '--foo' -> '--no-foo'
+ if option_string.startswith('no-', 2):
raise ValueError(f'invalid option name {option_string!r} '
f'for BooleanOptionalAction')
- option_string = '--no-' + option_string[2:]
+ option_string = option_string[:2] + 'no-' + option_string[2:]
_option_strings.append(option_string)
+ neg_option_strings.append(option_string)
+ elif len(option_string) > 2 and option_string[0] != option_string[1]:
+ # single-dash long option: '-foo' -> '-nofoo'
+ if option_string.startswith('no', 1):
+ raise ValueError(f'invalid option name {option_string!r} '
+ f'for BooleanOptionalAction')
+ option_string = option_string[:1] + 'no' + option_string[1:]
+ _option_strings.append(option_string)
+ neg_option_strings.append(option_string)
super().__init__(
option_strings=_option_strings,
required=required,
help=help,
deprecated=deprecated)
+ self.neg_option_strings = neg_option_strings
def __call__(self, parser, namespace, values, option_string=None):
if option_string in self.option_strings:
- setattr(namespace, self.dest, not option_string.startswith('--no-'))
+ setattr(namespace, self.dest, option_string not in self.neg_option_strings)
def format_usage(self):
return ' | '.join(self.option_strings)
self.assertEqual(str(cm.exception),
"invalid option name '--no-foo' for BooleanOptionalAction")
+class TestBooleanOptionalActionSingleDash(ParserTestCase):
+ """Tests BooleanOptionalAction with single dash"""
+
+ argument_signatures = [
+ Sig('-foo', '-x', action=argparse.BooleanOptionalAction),
+ ]
+ failures = ['--foo', '--no-foo', '-no-foo', '-no-x', '-nox']
+ successes = [
+ ('', NS(foo=None)),
+ ('-foo', NS(foo=True)),
+ ('-nofoo', NS(foo=False)),
+ ('-x', NS(foo=True)),
+ ]
+
+ def test_invalid_name(self):
+ parser = argparse.ArgumentParser()
+ with self.assertRaises(ValueError) as cm:
+ parser.add_argument('-nofoo', action=argparse.BooleanOptionalAction)
+ self.assertEqual(str(cm.exception),
+ "invalid option name '-nofoo' for BooleanOptionalAction")
+
+class TestBooleanOptionalActionAlternatePrefixChars(ParserTestCase):
+ """Tests BooleanOptionalAction with custom prefixes"""
+
+ parser_signature = Sig(prefix_chars='+-', add_help=False)
+ argument_signatures = [Sig('++foo', action=argparse.BooleanOptionalAction)]
+ failures = ['--foo', '--no-foo']
+ successes = [
+ ('', NS(foo=None)),
+ ('++foo', NS(foo=True)),
+ ('++no-foo', NS(foo=False)),
+ ]
+
+ def test_invalid_name(self):
+ parser = argparse.ArgumentParser(prefix_chars='+/')
+ with self.assertRaisesRegex(ValueError,
+ 'BooleanOptionalAction.*is not valid for positional arguments'):
+ parser.add_argument('--foo', action=argparse.BooleanOptionalAction)
+ with self.assertRaises(ValueError) as cm:
+ parser.add_argument('++no-foo', action=argparse.BooleanOptionalAction)
+ self.assertEqual(str(cm.exception),
+ "invalid option name '++no-foo' for BooleanOptionalAction")
+
+class TestBooleanOptionalActionSingleAlternatePrefixChar(ParserTestCase):
+ """Tests BooleanOptionalAction with single alternate prefix char"""
+
+ parser_signature = Sig(prefix_chars='+/', add_help=False)
+ argument_signatures = [
+ Sig('+foo', '+x', action=argparse.BooleanOptionalAction),
+ ]
+ failures = ['++foo', '++no-foo', '++nofoo',
+ '-no-foo', '-nofoo', '+no-foo', '-nofoo',
+ '+no-x', '+nox', '-no-x', '-nox']
+ successes = [
+ ('', NS(foo=None)),
+ ('+foo', NS(foo=True)),
+ ('+nofoo', NS(foo=False)),
+ ('+x', NS(foo=True)),
+ ]
+
+ def test_invalid_name(self):
+ parser = argparse.ArgumentParser(prefix_chars='+/')
+ with self.assertRaisesRegex(ValueError,
+ 'BooleanOptionalAction.*is not valid for positional arguments'):
+ parser.add_argument('-foo', action=argparse.BooleanOptionalAction)
+ with self.assertRaises(ValueError) as cm:
+ parser.add_argument('+nofoo', action=argparse.BooleanOptionalAction)
+ self.assertEqual(str(cm.exception),
+ "invalid option name '+nofoo' for BooleanOptionalAction")
+
class TestBooleanOptionalActionRequired(ParserTestCase):
"""Tests BooleanOptionalAction required"""