for bool, generate --no-xxxx option

This commit is contained in:
2019-04-02 21:02:08 +02:00
parent 075de80f73
commit 266cef224e
2 changed files with 120 additions and 65 deletions

View File

@ -12,10 +12,11 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from typing import Union, List, Optional
from argparse import ArgumentParser, Namespace, SUPPRESS, _HelpAction, HelpFormatter
from copy import copy
try:
from tiramisu import Config
from tiramisu.error import PropertiesOptionError
@ -146,8 +147,19 @@ class TiramisuCmdlineParser(ArgumentParser):
def add_subparsers(self, *args, **kwargs):
raise NotImplementedError('do not use add_subparsers')
def _gen_argument(self, name, properties):
if len(name) == 1 and 'longargument' not in properties:
def _gen_argument(self, name, longargument, no_prefix=False):
shortarg = len(name) == 1 and not longargument
if no_prefix:
if shortarg:
prefix = 'n'
else:
prefix = 'no-'
if '.' in name:
sname = name.rsplit('.', 1)
name = sname[0] + '.' + prefix + sname[1]
else:
name = prefix + name
if shortarg:
return self.prefix_chars + name
return self.prefix_chars * 2 + name
@ -182,67 +194,75 @@ class TiramisuCmdlineParser(ArgumentParser):
if option.issymlinkoption():
symlink_name = option.name(follow_symlink=True)
if symlink_name in actions:
actions[symlink_name][0].insert(0, self._gen_argument(option.name(), properties))
actions[symlink_name][0][0].insert(0, self._gen_argument(option.name(), 'longargument' in properties))
if len(actions[symlink_name]) == 2:
actions[symlink_name][1][0].insert(0, self._gen_argument(option.name(), False, True))
continue
if _forhelp and not obj.owner.isdefault() and obj.value.get():
if _forhelp and not obj.owner.isdefault() and obj.value.get() is not None:
if 'positional' not in properties:
self.prog += ' {}'.format(self._gen_argument(name, properties))
self.prog += ' {}'.format(self._gen_argument(name, 'longargument' in properties))
if option.type() != 'boolean':
self.prog += ' {}'.format(obj.value.get())
else:
if 'positional' in properties:
if option.type() == 'boolean':
raise ValueError('boolean option must not be positional')
if not 'mandatory' in properties:
raise ValueError('"positional" argument must be "mandatory" too')
args = [option.path()]
if _forhelp:
args = [option.path()]
kwargs['default'] = obj.value.default()
else:
args = [option.path()]
kwargs['default'] = obj.value.get()
kwargs['nargs'] = '?'
else:
kwargs['dest'] = option.path()
kwargs['default'] = SUPPRESS
args = [self._gen_argument(name, properties)]
if _forhelp and 'mandatory' in properties:
kwargs['required'] = True
if option.type() == 'boolean':
if 'mandatory' in properties:
raise ValueError('"mandatory" property is not allowed for BoolOption')
#if not isinstance(option.default(), bool):
# raise ValueError('default value is mandatory for BoolOption')
if obj.value.get() is False:
action = 'store_true'
else:
action = 'store_false'
kwargs['action'] = action
else:
if _forhelp:
value = obj.value.default()
else:
value = obj.value.get()
if value not in [None, []]:
#kwargs['default'] = kwargs['const'] = option.default()
#kwargs['action'] = 'store_const'
kwargs['nargs'] = '?'
if option.ismulti():
if _forhelp and 'mandatory' in properties:
kwargs['nargs'] = '+'
if option.type() == 'boolean':
if obj.value.get() is False:
action = 'store_true'
no_action = 'store_false'
else:
kwargs['nargs'] = '*'
if option.type() == 'string':
pass
elif option.type() == 'integer':
kwargs['type'] = int
elif option.type() == 'choice':
kwargs['choices'] = obj.value.list()
action = 'store_false'
no_action = 'store_true'
kwargs['action'] = action
args = [self._gen_argument(name, 'longargument' in properties)]
#
nkwargs = copy(kwargs)
nkwargs['action'] = no_action
del nkwargs['help']
nargs = [self._gen_argument(name, 'longargument' in properties, True)]
actions[option.name()] = [(args, kwargs), (nargs, nkwargs)]
continue
args = [self._gen_argument(name, 'longargument' in properties)]
if _forhelp:
value = obj.value.default()
else:
value = obj.value.get()
if value not in [None, []]:
#kwargs['default'] = kwargs['const'] = option.default()
#kwargs['action'] = 'store_const'
kwargs['nargs'] = '?'
if option.ismulti():
if _forhelp and 'mandatory' in properties:
kwargs['nargs'] = '+'
else:
pass
#raise NotImplementedError('not supported yet')
actions[option.name()] = (args, kwargs)
for args, kwargs in actions.values():
group.add_argument(*args, **kwargs)
kwargs['nargs'] = '*'
if option.type() == 'string':
pass
elif option.type() == 'integer':
kwargs['type'] = int
elif option.type() == 'choice':
kwargs['choices'] = obj.value.list()
else:
pass
#raise NotImplementedError('not supported yet')
actions[option.name()] = [(args, kwargs)]
for values in actions.values():
for args, kwargs in values:
group.add_argument(*args, **kwargs)
def parse_args(self,
*args,
@ -272,7 +292,7 @@ class TiramisuCmdlineParser(ArgumentParser):
name = key
else:
name = key.rsplit('.', 1)[1]
args = self._gen_argument(name, self.config.option(key).property.get())
args = self._gen_argument(name, 'longargument' in self.config.option(key).property.get())
else:
args = key
if not self.fullpath and '.' in args: