chiark / gitweb /
python: Provide feature for argparse --[no-]foo options
[secnet.git] / argparseactionnoyes.py
1 # Python argparse --[no-]foo options
2 #
3 # Copyright 2012 "Omnifarious" (a user on StackOverFlow)
4 # Copyright 2013 "btel" (a user on StackOverFlow)
5 #
6 # https://stackoverflow.com/questions/9234258/in-python-argparse-is-it-possible-to-have-paired-no-something-something-arg/20422915#20422915
7 #
8 # CC-BY-SA 4.0
9 # by virtue of
10 # https://stackoverflow.com/legal/terms-of-service#licensing
11 # which says everything is CC-BY-SA and has a link to v4.0
12 # (And which is therefore compatible with secnet's GPLv3+)
13 #
14 # all retrieved 4.11.2019
15
16 import argparse
17
18 class ActionNoYes(argparse.Action):
19     def __init__(self, option_strings, dest, default=None, required=False, help=None):
20
21         if default is None:
22             raise ValueError('You must provide a default with Yes/No action')
23         if len(option_strings)!=1:
24             raise ValueError('Only single argument is allowed with YesNo action')
25         opt = option_strings[0]
26         if not opt.startswith('--'):
27             raise ValueError('Yes/No arguments must be prefixed with --')
28
29         opt = opt[2:]
30         opts = ['--' + opt, '--no-' + opt]
31         super(ActionNoYes, self).__init__(opts, dest, nargs=0, const=None, 
32                                           default=default, required=required, help=help)
33     def __call__(self, parser, namespace, values, option_strings=None):
34         if option_strings.startswith('--no-'):
35             setattr(namespace, self.dest, False)
36         else:
37             setattr(namespace, self.dest, True)