From 061577fba719212f016ef27842f6da2a16297b29 Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Fri, 1 Nov 2024 10:40:52 +0100 Subject: [PATCH] fix: black --- pyproject.toml | 6 +- tiramisu_cmdline_parser/__init__.py | 4 +- tiramisu_cmdline_parser/api.py | 593 ++++++++++++++++------------ 3 files changed, 337 insertions(+), 266 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index eba22c4..3d29b88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,11 +5,10 @@ requires = ["flit_core >=3.8.0,<4"] [project] name = "tiramisu_cmdline_parser" version = "0.6.0rc0" -authors = [ - {name = "Emmanuel Garette", email = "gnunux@gnunux.info"}, -] +authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}] readme = "README.md" description = "command-line parser using Tiramisu" +requires-python = ">=3.8" license = {file = "LICENSE"} classifiers = [ "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", @@ -39,3 +38,4 @@ tag_format = "$version" version_scheme = "pep440" version_provider = "pep621" update_changelog_on_bump = true +changelog_merge_prerelease = true diff --git a/tiramisu_cmdline_parser/__init__.py b/tiramisu_cmdline_parser/__init__.py index dfc2aa9..0214bdc 100644 --- a/tiramisu_cmdline_parser/__init__.py +++ b/tiramisu_cmdline_parser/__init__.py @@ -13,12 +13,14 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . from typing import Union, List, Dict, Tuple, Optional, Any + try: from .api import TiramisuCmdlineParser except ImportError as err: import warnings + warnings.warn("cannot not import TiramisuCmdlineParser {err}", ImportWarning) TiramisuCmdlineParser = None __version__ = "0.5" -__all__ = ('TiramisuCmdlineParser',) +__all__ = ("TiramisuCmdlineParser",) diff --git a/tiramisu_cmdline_parser/api.py b/tiramisu_cmdline_parser/api.py index c54ab99..b11dd12 100644 --- a/tiramisu_cmdline_parser/api.py +++ b/tiramisu_cmdline_parser/api.py @@ -13,19 +13,28 @@ # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . from typing import Union, List, Dict, Tuple, Optional, Any -from argparse import ArgumentParser, Namespace, SUPPRESS, _HelpAction, HelpFormatter, ArgumentDefaultsHelpFormatter +from argparse import ( + ArgumentParser, + Namespace, + SUPPRESS, + _HelpAction, + HelpFormatter, + ArgumentDefaultsHelpFormatter, +) from copy import copy from gettext import gettext as _ -#try: +# try: from tiramisu import Config from tiramisu.error import PropertiesOptionError, LeadershipError, ConfigError -#except ImportError: + +# except ImportError: # Config = None # from tiramisu_api.error import PropertiesOptionError # LeadershipError = ValueError try: from tiramisu_api import Config as ConfigJson + if Config is None: Config = ConfigJson except ImportError: @@ -37,23 +46,26 @@ def get_choice_list(config, properties, display): if isinstance(choice, int): return str(choice) return choice - choices = [convert(choice) for choice in config.value.list() if choice != '' and choice is not None] + + choices = [ + convert(choice) + for choice in config.value.list() + if choice != "" and choice is not None + ] if display: - choices = '{{{}}}'.format(','.join(choices)) - if 'mandatory' not in properties: - choices = '[{}]'.format(choices) + choices = "{{{}}}".format(",".join(choices)) + if "mandatory" not in properties: + choices = "[{}]".format(choices) return choices class TiramisuNamespace(Namespace): - def __init__(self, - config: Config, - root: Optional[str]) -> None: - super().__setattr__('_config', config) - super().__setattr__('_root', root) - super().__setattr__('list_force_no', {}) - super().__setattr__('list_force_del', {}) - super().__setattr__('arguments', {}) + def __init__(self, config: Config, root: Optional[str]) -> None: + super().__setattr__("_config", config) + super().__setattr__("_root", root) + super().__setattr__("list_force_no", {}) + super().__setattr__("list_force_del", {}) + super().__setattr__("arguments", {}) self._populate() super().__init__() @@ -73,10 +85,11 @@ class TiramisuNamespace(Namespace): value = None super().__setattr__(option.path(), value) - def __setattr__(self, - key: str, - value: Any, - ) -> None: + def __setattr__( + self, + key: str, + value: Any, + ) -> None: if key in self.list_force_no: true_key = self.list_force_no[key] elif key in self.list_force_del: @@ -87,14 +100,14 @@ class TiramisuNamespace(Namespace): if option.isfollower(): _setattr = self._setattr_follower if not value[0].isdecimal(): - raise ValueError('index must be a number, not {}'.format(value[0])) + raise ValueError("index must be a number, not {}".format(value[0])) index = int(value[0]) option = self._config.option(true_key, index) - true_value = ','.join(value[1:]) + true_value = ",".join(value[1:]) else: _setattr = self._setattr true_value = value - if option.type() == 'choice': + if option.type() == "choice": # HACK if integer in choice values = option.value.list() if isinstance(value, list): @@ -116,9 +129,9 @@ class TiramisuNamespace(Namespace): else: _setattr(option, true_key, key, value) except ValueError as err: - if option.type() == 'choice': + if option.type() == "choice": values = option.value.list() - display_value = '' + display_value = "" if isinstance(true_value, list): for val in value: if val not in values: @@ -127,31 +140,31 @@ class TiramisuNamespace(Namespace): else: display_value = true_value choices = get_choice_list(option, option.property.get(), False) - raise ValueError("argument {}: invalid choice: '{}' (choose from {})".format(self.arguments[key], display_value, ', '.join([f"'{val}'" for val in choices]))) + raise ValueError( + "argument {}: invalid choice: '{}' (choose from {})".format( + self.arguments[key], + display_value, + ", ".join([f"'{val}'" for val in choices]), + ) + ) else: raise err - def _setattr(self, - option: 'Option', - true_key: str, - key: str, - value: Any) -> None: - if option.ismulti() and \ - value is not None and \ - not isinstance(value, list): + def _setattr(self, option: "Option", true_key: str, key: str, value: Any) -> None: + if option.ismulti() and value is not None and not isinstance(value, list): value = [value] try: option.value.set(value) except PropertiesOptionError: - raise AttributeError('unrecognized arguments: {}'.format(self.arguments[key])) + raise AttributeError( + "unrecognized arguments: {}".format(self.arguments[key]) + ) - def _setattr_follower(self, - option: 'Option', - true_key: str, - key: str, - value: Any) -> None: + def _setattr_follower( + self, option: "Option", true_key: str, key: str, value: Any + ) -> None: index = int(value[0]) - if option.type() == 'boolean': + if option.type() == "boolean": value = key not in self.list_force_no elif option.issubmulti(): value = value[1:] @@ -161,25 +174,27 @@ class TiramisuNamespace(Namespace): class TiramisuHelpFormatter: - def _get_default_metavar_for_optional(self, - action): + def _get_default_metavar_for_optional(self, action): ret = super()._get_default_metavar_for_optional(action) - if '.' in ret: - ret = ret.rsplit('.', 1)[1] + if "." in ret: + ret = ret.rsplit(".", 1)[1] return ret class _Section(HelpFormatter._Section): def format_help(self): # Remove empty OD - if self.formatter.remove_empty_od and \ - len(self.items) == 1 and \ - self.items[0][0].__name__ == '_format_text': - return '' + if ( + self.formatter.remove_empty_od + and len(self.items) == 1 + and self.items[0][0].__name__ == "_format_text" + ): + return "" return super().format_help() class _TiramisuHelpAction(_HelpAction): needs = False + def __call__(self, *args, **kwargs): _TiramisuHelpAction.needs = True @@ -188,31 +203,38 @@ class _TiramisuHelpAction(_HelpAction): class _BuildKwargs: - def __init__(self, - name: str, - option: 'Option', - cmdlineparser: 'TiramisuCmdlineParser', - properties: List[str], - force_no: bool, - force_del: bool, - add_extra_options: bool, - display_modified_value: bool, - not_display: bool) -> None: + def __init__( + self, + name: str, + option: "Option", + cmdlineparser: "TiramisuCmdlineParser", + properties: List[str], + force_no: bool, + force_del: bool, + add_extra_options: bool, + display_modified_value: bool, + not_display: bool, + ) -> None: self.kwargs = {} self.cmdlineparser = cmdlineparser self.properties = properties self.force_no = force_no self.force_del = force_del - if ((not self.force_no or not add_extra_options) or (not_display and not display_modified_value)) and not self.force_del: + if ( + (not self.force_no or not add_extra_options) + or (not_display and not display_modified_value) + ) and not self.force_del: if self.force_no: - description = option.information.get('negative_description', None) + description = option.information.get("negative_description", None) else: description = None if description is None: description = option.description() - self.kwargs['help'] = description - if 'positional' not in self.properties: - is_short_name = self.cmdlineparser._is_short_name(name, 'longargument' in self.properties) + self.kwargs["help"] = description + if "positional" not in self.properties: + is_short_name = self.cmdlineparser._is_short_name( + name, "longargument" in self.properties + ) if self.force_no: ga_name = self.gen_argument_name(name, is_short_name) ga_path = self.gen_argument_name(option.path(), is_short_name) @@ -223,7 +245,7 @@ class _BuildKwargs: self.cmdlineparser.namespace.list_force_del[ga_path] = option.path() else: ga_name = name - self.kwargs['dest'] = self.gen_argument_name(option.path(), False) + self.kwargs["dest"] = self.gen_argument_name(option.path(), False) argument = self.cmdlineparser._gen_argument(ga_name, is_short_name) self.cmdlineparser.namespace.arguments[option.path()] = argument self.args = [argument] @@ -231,14 +253,13 @@ class _BuildKwargs: self.cmdlineparser.namespace.arguments[option.path()] = option.path() self.args = [option.path()] - def __setitem__(self, - key: str, - value: Any) -> None: + def __setitem__(self, key: str, value: Any) -> None: self.kwargs[key] = value - def add_argument(self, - option: 'Option'): - is_short_name = self.cmdlineparser._is_short_name(option.name(), 'longargument' in self.properties) + def add_argument(self, option: "Option"): + is_short_name = self.cmdlineparser._is_short_name( + option.name(), "longargument" in self.properties + ) if self.force_no: name = self.gen_argument_name(option.name(), is_short_name) elif self.force_del: @@ -252,22 +273,22 @@ class _BuildKwargs: def gen_argument_name(self, name, is_short_name): if self.force_no: if is_short_name: - prefix = 'n' + prefix = "n" else: - prefix = 'no-' - if '.' in name: - sname = name.rsplit('.', 1) - name = sname[0] + '.' + prefix + sname[1] + prefix = "no-" + if "." in name: + sname = name.rsplit(".", 1) + name = sname[0] + "." + prefix + sname[1] else: name = prefix + name if self.force_del: if is_short_name: - prefix = 'p' + prefix = "p" else: - prefix = 'pop-' - if '.' in name: - sname = name.rsplit('.', 1) - name = sname[0] + '.' + prefix + sname[1] + prefix = "pop-" + if "." in name: + sname = name.rsplit(".", 1) + name = sname[0] + "." + prefix + sname[1] else: name = prefix + name return name @@ -277,19 +298,21 @@ class _BuildKwargs: class TiramisuCmdlineParser(ArgumentParser): - def __init__(self, - config: Union[Config, ConfigJson], - *args, - root: str=None, - fullpath: bool=True, - remove_empty_od: bool=False, - display_modified_value: bool=True, - formatter_class=ArgumentDefaultsHelpFormatter, - unrestraint: bool=False, - add_extra_options: bool=True, - short_name_max_len: int=1, - _forhelp: bool=False, - **kwargs): + def __init__( + self, + config: Union[Config, ConfigJson], + *args, + root: str = None, + fullpath: bool = True, + remove_empty_od: bool = False, + display_modified_value: bool = True, + formatter_class=ArgumentDefaultsHelpFormatter, + unrestraint: bool = False, + add_extra_options: bool = True, + short_name_max_len: int = 1, + _forhelp: bool = False, + **kwargs, + ): if not _forhelp: unrestraint = True self.fullpath = fullpath @@ -301,9 +324,11 @@ class TiramisuCmdlineParser(ArgumentParser): self.display_modified_value = display_modified_value self.short_name_max_len = short_name_max_len if TiramisuHelpFormatter not in formatter_class.__mro__: - formatter_class = type('TiramisuHelpFormatter', (TiramisuHelpFormatter, formatter_class), {}) + formatter_class = type( + "TiramisuHelpFormatter", (TiramisuHelpFormatter, formatter_class), {} + ) formatter_class.remove_empty_od = self.remove_empty_od - kwargs['formatter_class'] = formatter_class + kwargs["formatter_class"] = formatter_class if not _forhelp and self.unrestraint: subconfig = self.config.unrestraint else: @@ -314,21 +339,20 @@ class TiramisuCmdlineParser(ArgumentParser): subconfig = subconfig.option(self.root) self.namespace = TiramisuNamespace(self.config, self.root) super().__init__(*args, **kwargs) - self.register('action', 'help', _TiramisuHelpAction) - self._config_to_argparser(_forhelp, - subconfig, - self.root, - ) + self.register("action", "help", _TiramisuHelpAction) + self._config_to_argparser( + _forhelp, + subconfig, + self.root, + ) def _pop_action_class(self, kwargs, default=None): ret = super()._pop_action_class(kwargs, default) - if kwargs.get('action') != 'help' and kwargs.get('dest') != 'help': + if kwargs.get("action") != "help" and kwargs.get("dest") != "help": return ret return _TiramisuHelpAction - def _match_arguments_partial(self, - actions, - arg_string_pattern): + def _match_arguments_partial(self, actions, arg_string_pattern): # used only when check first proposal for first value # we have to remove all actions with propertieserror # so only first settable option will be returned @@ -358,63 +382,61 @@ class TiramisuCmdlineParser(ArgumentParser): if args != args_ and args_ and args_[0].startswith(self.prefix_chars): # option that was disabled are no more disable # so create a new parser - new_parser = TiramisuCmdlineParser(self.config, - self.prog, - root=self.root, - remove_empty_od=self.remove_empty_od, - display_modified_value=self.display_modified_value, - formatter_class=self.formatter_class, - epilog=self.epilog, - description=self.description, - unrestraint=self.unrestraint, - add_extra_options=self.add_extra_options, - short_name_max_len=self.short_name_max_len, - fullpath=self.fullpath) - namespace_, args_ = new_parser._parse_known_args(args_, new_parser.namespace) + new_parser = TiramisuCmdlineParser( + self.config, + self.prog, + root=self.root, + remove_empty_od=self.remove_empty_od, + display_modified_value=self.display_modified_value, + formatter_class=self.formatter_class, + epilog=self.epilog, + description=self.description, + unrestraint=self.unrestraint, + add_extra_options=self.add_extra_options, + short_name_max_len=self.short_name_max_len, + fullpath=self.fullpath, + ) + namespace_, args_ = new_parser._parse_known_args( + args_, new_parser.namespace + ) else: - if self._registries['action']['help'].needs: + if self._registries["action"]["help"].needs: # display help only when all variables assignemnt are done - self._registries['action']['help'].needs = False - helper = self._registries['action']['help'](None) + self._registries["action"]["help"].needs = False + helper = self._registries["action"]["help"](None) helper.display(self) return namespace_, args_ def add_argument(self, *args, **kwargs): - if args == ('-h', '--help'): + if args == ("-h", "--help"): super().add_argument(*args, **kwargs) else: - raise NotImplementedError(_('do not use add_argument')) + raise NotImplementedError(_("do not use add_argument")) def add_arguments(self, *args, **kwargs): - raise NotImplementedError(_('do not use add_argument')) + raise NotImplementedError(_("do not use add_argument")) def add_subparsers(self, *args, **kwargs): - raise NotImplementedError(_('do not use add_subparsers')) + raise NotImplementedError(_("do not use add_subparsers")) - def _option_is_not_default(self, - properties, - type, - name, - value): - if 'positional' not in properties: - is_short_name = self._is_short_name(name, 'longargument' in properties) - self.prog += ' {}'.format(self._gen_argument(name, is_short_name)) - if type != 'boolean': + def _option_is_not_default(self, properties, type, name, value): + if "positional" not in properties: + is_short_name = self._is_short_name(name, "longargument" in properties) + self.prog += " {}".format(self._gen_argument(name, is_short_name)) + if type != "boolean": if isinstance(value, list): for val in value: self.prog += ' "{}"'.format(val) else: self.prog += ' "{}"'.format(value) - def _config_list(self, - config: Config, - prefix: Optional[str], - _forhelp: bool, - group, level): + def _config_list( + self, config: Config, prefix: Optional[str], _forhelp: bool, group, level + ): obj = None for obj in config: # do not display frozen option - if 'frozen' in obj.property.get(): + if "frozen" in obj.property.get(): continue if obj.isoptiondescription(): if _forhelp: @@ -425,11 +447,15 @@ class TiramisuCmdlineParser(ArgumentParser): else: newgroup = group if prefix: - prefix_ = prefix + '.' + obj.name() + prefix_ = prefix + "." + obj.name() else: prefix_ = obj.path() self._config_to_argparser(_forhelp, obj, prefix_, newgroup, level + 1) - elif self.add_extra_options and obj.type() == 'boolean' and not obj.issymlinkoption(): + elif ( + self.add_extra_options + and obj.type() == "boolean" + and not obj.issymlinkoption() + ): if not obj.isleader(): yield obj, False, None yield obj, True, None @@ -441,10 +467,20 @@ class TiramisuCmdlineParser(ArgumentParser): yield obj, None, False yield obj, None, True else: - if not obj.issymlinkoption() and obj.type() == 'boolean' and obj.value.get() is True: - negative_description = obj.information.get('negative_description', None) + if ( + not obj.issymlinkoption() + and obj.type() == "boolean" + and obj.value.get() is True + ): + negative_description = obj.information.get( + "negative_description", None + ) if _forhelp and not negative_description: - raise ValueError(_(f'the boolean "{obj.path()}" cannot have a default value to "True" with option add_extra_options if there is no negative_description')) + raise ValueError( + _( + f'the boolean "{obj.path()}" cannot have a default value to "True" with option add_extra_options if there is no negative_description' + ) + ) yield obj, True, None else: yield obj, None, None @@ -457,33 +493,34 @@ class TiramisuCmdlineParser(ArgumentParser): except ConfigError: pass - def _config_to_argparser(self, - _forhelp: bool, - config, - prefix: Optional[str], - group=None, - level=0) -> None: + def _config_to_argparser( + self, _forhelp: bool, config, prefix: Optional[str], group=None, level=0 + ) -> None: if group is None: group = super() actions = {} leadership_len = None options_is_not_default = {} - for option, force_no, force_del in self._config_list(config, prefix, _forhelp, group, level): + for option, force_no, force_del in self._config_list( + config, prefix, _forhelp, group, level + ): name = option.name() if name.startswith(self.prefix_chars): - raise ValueError(_('name cannot startswith "{}"').format(self.prefix_chars)) + raise ValueError( + _('name cannot startswith "{}"').format(self.prefix_chars) + ) if option.issymlinkoption(): symlink_name = option.option().name() if symlink_name in options_is_not_default: - options_is_not_default[symlink_name]['name'] = name + options_is_not_default[symlink_name]["name"] = name if symlink_name in actions: for action in actions[symlink_name]: action.add_argument(option) continue if force_del: value = None -# elif force_no: -# value = not option.value.get() + # elif force_no: + # value = not option.value.get() elif option.isleader(): value = option.value.get() leadership_len = len(value) @@ -494,22 +531,46 @@ class TiramisuCmdlineParser(ArgumentParser): value = [] try: for index in range(leadership_len): - value.append(self.config.option(option.path(), index).value.get()) + value.append( + self.config.option(option.path(), index).value.get() + ) except: value = None else: value = option.value.get() if self.fullpath and prefix: - name = prefix + '.' + name + name = prefix + "." + name properties = option.property.get() - not_display = not option.isfollower() and not option.owner.isdefault() and value is not None - kwargs = _BuildKwargs(name, option, self, properties, force_no, force_del, self.add_extra_options, self.display_modified_value, not_display) - if _forhelp and not_display and ((value is not False and not force_no) or (value is False and force_no)): - options_is_not_default[option.name()] = {'properties': properties, - 'type': option.type(), - 'name': name, - 'value': value, - } + not_display = ( + not option.isfollower() + and not option.owner.isdefault() + and value is not None + ) + kwargs = _BuildKwargs( + name, + option, + self, + properties, + force_no, + force_del, + self.add_extra_options, + self.display_modified_value, + not_display, + ) + if ( + _forhelp + and not_display + and ( + (value is not False and not force_no) + or (value is False and force_no) + ) + ): + options_is_not_default[option.name()] = { + "properties": properties, + "type": option.type(), + "name": name, + "value": value, + } if not self.display_modified_value: continue if force_no: @@ -517,86 +578,89 @@ class TiramisuCmdlineParser(ArgumentParser): else: default = option.value.default() if isinstance(default, list): - str_default_value = ','.join([str(v) for v in default]) + str_default_value = ",".join([str(v) for v in default]) else: str_default_value = default - if 'positional' in properties: - if option.type() == 'boolean': - raise ValueError(_('boolean option must not be positional')) - if not 'mandatory' in properties: + 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') if _forhelp: - kwargs['default'] = str_default_value + kwargs["default"] = str_default_value else: - kwargs['default'] = value - kwargs['nargs'] = '?' + kwargs["default"] = value + kwargs["nargs"] = "?" else: if _forhelp and not option.isleader(): if default not in [None, []]: - kwargs['default'] = str_default_value + kwargs["default"] = str_default_value else: - kwargs['default'] = SUPPRESS + kwargs["default"] = SUPPRESS else: - kwargs['default'] = SUPPRESS - if _forhelp and 'mandatory' in properties: - kwargs['required'] = True - if not force_del and option.type() == 'boolean': + kwargs["default"] = SUPPRESS + if _forhelp and "mandatory" in properties: + kwargs["required"] = True + if not force_del and option.type() == "boolean": if not option.isfollower(): - if 'storefalse' in properties: + if "storefalse" in properties: if force_no: - action = 'store_true' + action = "store_true" else: - action = 'store_false' + action = "store_false" elif force_no: - action = 'store_false' + action = "store_false" else: - action = 'store_true' - kwargs['action'] = action + action = "store_true" + kwargs["action"] = action else: - kwargs['metavar'] = 'INDEX' - if option.type() != 'boolean' or force_del: + kwargs["metavar"] = "INDEX" + if option.type() != "boolean" or force_del: if not force_del: if _forhelp: value = option.value.default() if value not in [None, []]: - #kwargs['default'] = kwargs['const'] = option.default() - #kwargs['action'] = 'store_const' - kwargs['nargs'] = '?' + # kwargs['default'] = kwargs['const'] = option.default() + # kwargs['action'] = 'store_const' + kwargs["nargs"] = "?" if not option.isfollower() and option.ismulti(): - if _forhelp and 'mandatory' in properties: - kwargs['nargs'] = '+' + if _forhelp and "mandatory" in properties: + kwargs["nargs"] = "+" else: - kwargs['nargs'] = '*' - if option.isfollower() and not option.type() == 'boolean': + kwargs["nargs"] = "*" + if option.isfollower() and not option.type() == "boolean": metavar = option.name().upper() if option.issubmulti(): - kwargs['nargs'] = '+' + kwargs["nargs"] = "+" else: - kwargs['nargs'] = 2 - if _forhelp and 'mandatory' not in properties: - metavar = '[{}]'.format(metavar) - if option.type() == 'choice': + kwargs["nargs"] = 2 + if _forhelp and "mandatory" not in properties: + metavar = "[{}]".format(metavar) + if option.type() == "choice": # do not manage choice with argparse there is problem with integer problem - kwargs['metavar'] = ('INDEX', get_choice_list(option, properties, True)) + kwargs["metavar"] = ( + "INDEX", + get_choice_list(option, properties, True), + ) else: - kwargs['metavar'] = ('INDEX', metavar) + kwargs["metavar"] = ("INDEX", metavar) if force_del: - kwargs['metavar'] = 'INDEX' - kwargs['type'] = int - elif option.type() == 'string': + kwargs["metavar"] = "INDEX" + kwargs["type"] = int + elif option.type() == "string": pass - elif option.type() == 'integer' or option.type() == 'boolean': + elif option.type() == "integer" or option.type() == "boolean": # when boolean we are here only if follower - kwargs['type'] = int - if _forhelp and option.type() == 'boolean': - kwargs['metavar'] = 'INDEX' - kwargs['nargs'] = 1 - elif option.type() == 'choice' and not option.isfollower(): + kwargs["type"] = int + if _forhelp and option.type() == "boolean": + kwargs["metavar"] = "INDEX" + kwargs["nargs"] = 1 + elif option.type() == "choice" and not option.isfollower(): # do not manage choice with argparse there is problem with integer problem - kwargs['choices'] = get_choice_list(option, properties, False) - elif option.type() == 'float': - kwargs['type'] = float + kwargs["choices"] = get_choice_list(option, properties, False) + elif option.type() == "float": + kwargs["type"] = float else: pass actions.setdefault(option.name(), []).append(kwargs) @@ -604,91 +668,96 @@ class TiramisuCmdlineParser(ArgumentParser): for option_is_not_default in options_is_not_default.values(): self._option_is_not_default(**option_is_not_default) for values in actions.values(): -# for value in values: + # for value in values: value = values[0] args, kwargs = value.get() group.add_argument(*args, **kwargs) -# def _valid_mandatory(self): -# pass -# - def parse_args(self, - *args, - valid_mandatory=True, - **kwargs): - kwargs['namespace'] = self.namespace + # def _valid_mandatory(self): + # pass + # + def parse_args(self, *args, valid_mandatory=True, **kwargs): + kwargs["namespace"] = self.namespace try: namespaces = super().parse_args(*args, **kwargs) except PropertiesOptionError as err: name = err._subconfig.path properties = self.config.option(name).property.get() - if self.fullpath and 'positional' not in properties: - if len(name) == 1 and 'longargument' not in properties: + if self.fullpath and "positional" not in properties: + if len(name) == 1 and "longargument" not in properties: name = self.prefix_chars + name else: name = self.prefix_chars * 2 + name - if err.proptype == ['mandatory']: - self.error('the following arguments are required: {}'.format(name)) + if err.proptype == ["mandatory"]: + self.error("the following arguments are required: {}".format(name)) else: - self.error('unrecognized arguments: {}'.format(name)) + self.error("unrecognized arguments: {}".format(name)) if valid_mandatory: errors = [] for option in self.config.value.mandatory(): properties = option.property.get() if not option.isfollower(): - if 'positional' not in properties: + if "positional" not in properties: if self.fullpath: name = option.path() else: name = option.name() - is_short_name = self._is_short_name(name, 'longargument' in option.property.get()) + is_short_name = self._is_short_name( + name, "longargument" in option.property.get() + ) args = self._gen_argument(name, is_short_name) else: args = option.path() else: - if 'positional' not in properties: + if "positional" not in properties: args = self._gen_argument(option.path(), False) else: args = option.path() - if not self.fullpath and '.' in args: - args = args.rsplit('.', 1)[1] - if 'positional' not in properties: + if not self.fullpath and "." in args: + args = args.rsplit(".", 1)[1] + if "positional" not in properties: args = self._gen_argument(args, False) errors.append(args) if errors: - self.error('the following arguments are required: {}'.format(', '.join(errors))) + self.error( + "the following arguments are required: {}".format(", ".join(errors)) + ) return namespaces - def format_usage(self, - *args, - **kwargs): - help_formatter = TiramisuCmdlineParser(self.config, - self.prog, - root=self.root, - fullpath=self.fullpath, - remove_empty_od=self.remove_empty_od, - display_modified_value=self.display_modified_value, - formatter_class=self.formatter_class, - add_extra_options=self.add_extra_options, - short_name_max_len=self.short_name_max_len, - epilog=self.epilog, - description=self.description, - _forhelp=True) - return super(TiramisuCmdlineParser, help_formatter).format_usage(*args, **kwargs) + def format_usage(self, *args, **kwargs): + help_formatter = TiramisuCmdlineParser( + self.config, + self.prog, + root=self.root, + fullpath=self.fullpath, + remove_empty_od=self.remove_empty_od, + display_modified_value=self.display_modified_value, + formatter_class=self.formatter_class, + add_extra_options=self.add_extra_options, + short_name_max_len=self.short_name_max_len, + epilog=self.epilog, + description=self.description, + _forhelp=True, + ) + return super(TiramisuCmdlineParser, help_formatter).format_usage( + *args, **kwargs + ) def format_help(self): - help_formatter = TiramisuCmdlineParser(self.config, - self.prog, - root=self.root, - fullpath=self.fullpath, - remove_empty_od=self.remove_empty_od, - display_modified_value=self.display_modified_value, - formatter_class=self.formatter_class, - add_extra_options=self.add_extra_options, - short_name_max_len=self.short_name_max_len, - epilog=self.epilog, - description=self.description, - _forhelp=True) + help_formatter = TiramisuCmdlineParser( + self.config, + self.prog, + root=self.root, + fullpath=self.fullpath, + remove_empty_od=self.remove_empty_od, + display_modified_value=self.display_modified_value, + formatter_class=self.formatter_class, + add_extra_options=self.add_extra_options, + short_name_max_len=self.short_name_max_len, + epilog=self.epilog, + description=self.description, + _forhelp=True, + ) return super(TiramisuCmdlineParser, help_formatter).format_help() def get_config(self):