diff --git a/tests/test_help.py b/tests/test_help.py index 5e70123..0c4848f 100644 --- a/tests/test_help.py +++ b/tests/test_help.py @@ -7,7 +7,11 @@ from argparse import RawDescriptionHelpFormatter from tiramisu_cmdline_parser import TiramisuCmdlineParser from tiramisu import IntOption, StrOption, BoolOption, ChoiceOption, \ SymLinkOption, OptionDescription, Config -from tiramisu_api import Config as JsonConfig +try: + from tiramisu_api import Config as JsonConfig + params = ['tiramisu', 'tiramisu-json'] +except: + params = ['tiramisu'] @@ -31,7 +35,7 @@ def get_config(json): return jconfig -@pytest.fixture(params=['tiramisu', 'tiramisu-json']) +@pytest.fixture(params=params) def json(request): return request.param diff --git a/tests/test_leadership.py b/tests/test_leadership.py index 1272916..ffc7244 100644 --- a/tests/test_leadership.py +++ b/tests/test_leadership.py @@ -6,7 +6,11 @@ import pytest from tiramisu_cmdline_parser import TiramisuCmdlineParser from tiramisu import IntOption, StrOption, BoolOption, ChoiceOption, \ SymLinkOption, OptionDescription, Leadership, Config, submulti -from tiramisu_api import Config as JsonConfig +try: + from tiramisu_api import Config as JsonConfig + params = ['tiramisu', 'tiramisu-json'] +except: + params = ['tiramisu'] def get_config(json, with_mandatory=False): @@ -31,7 +35,7 @@ def get_config(json, with_mandatory=False): return jconfig -@pytest.fixture(params=['tiramisu', 'tiramisu-api']) +@pytest.fixture(params=params) def json(request): return request.param diff --git a/tests/test_optiondescription.py b/tests/test_optiondescription.py index 290901e..7691383 100644 --- a/tests/test_optiondescription.py +++ b/tests/test_optiondescription.py @@ -6,7 +6,11 @@ import pytest from tiramisu_cmdline_parser import TiramisuCmdlineParser from tiramisu import IntOption, StrOption, BoolOption, ChoiceOption, \ SymLinkOption, OptionDescription, Config -from tiramisu_api import Config as JsonConfig +try: + from tiramisu_api import Config as JsonConfig + params = ['tiramisu', 'tiramisu-json'] +except: + params = ['tiramisu'] def get_config(json, has_tree=False, default_verbosity=False, add_long=False, add_store_false=False, empty_optiondescription=False): @@ -59,7 +63,7 @@ def get_config(json, has_tree=False, default_verbosity=False, add_long=False, ad return jconfig -@pytest.fixture(params=['tiramisu', 'tiramisu-json']) +@pytest.fixture(params=params) def json(request): return request.param diff --git a/tests/test_readme.py b/tests/test_readme.py index 65089ee..ca6c4e3 100644 --- a/tests/test_readme.py +++ b/tests/test_readme.py @@ -6,7 +6,11 @@ import pytest from tiramisu_cmdline_parser import TiramisuCmdlineParser from tiramisu import IntOption, StrOption, BoolOption, ChoiceOption, \ SymLinkOption, OptionDescription, Config -from tiramisu_api import Config as JsonConfig +try: + from tiramisu_api import Config as JsonConfig + params = ['tiramisu', 'tiramisu-json'] +except: + params = ['tiramisu'] def get_config(json, has_tree=False, default_verbosity=False, add_long=False, add_store_false=False): @@ -67,7 +71,7 @@ def get_config(json, has_tree=False, default_verbosity=False, add_long=False, ad return jconfig -@pytest.fixture(params=['tiramisu', 'tiramisu-json']) +@pytest.fixture(params=params) def json(request): return request.param @@ -461,7 +465,7 @@ prog.py: error: unrecognized arguments: --int f = StringIO() with redirect_stderr(f): try: - parser.parse_args(['none', '--int']) + parser.parse_args(['none', '--int', '1']) except SystemExit as err: assert str(err) == "2" else: @@ -477,7 +481,7 @@ prog.py: error: unrecognized arguments: --int f = StringIO() with redirect_stderr(f): try: - parser.parse_args(['none', '--int']) + parser.parse_args(['none', '--int', '1']) except SystemExit as err: assert str(err) == "2" else: @@ -493,7 +497,7 @@ prog.py: error: unrecognized arguments: --root.int f = StringIO() with redirect_stderr(f): try: - parser.parse_args(['none', '--root.int']) + parser.parse_args(['none', '--root.int', '1']) except SystemExit as err: assert str(err) == "2" else: @@ -509,7 +513,7 @@ prog.py: error: unrecognized arguments: --root.int f = StringIO() with redirect_stderr(f): try: - parser.parse_args(['none', '--root.int']) + parser.parse_args(['none', '--root.int', '1']) except SystemExit as err: assert str(err) == "2" else: @@ -525,7 +529,7 @@ prog.py: error: unrecognized arguments: --int f = StringIO() with redirect_stderr(f): try: - parser.parse_args(['none', '--int']) + parser.parse_args(['none', '--int', '1']) except SystemExit as err: assert str(err) == "2" else: @@ -541,7 +545,7 @@ prog.py: error: unrecognized arguments: --int f = StringIO() with redirect_stderr(f): try: - parser.parse_args(['none', '--int']) + parser.parse_args(['none', '--int', '1']) except SystemExit as err: assert str(err) == "2" else: diff --git a/tests/test_shortarg.py b/tests/test_shortarg.py index 9481623..58b5a69 100644 --- a/tests/test_shortarg.py +++ b/tests/test_shortarg.py @@ -6,10 +6,14 @@ from contextlib import redirect_stderr from tiramisu_cmdline_parser import TiramisuCmdlineParser from tiramisu import IntOption, StrOption, BoolOption, ChoiceOption, \ SymLinkOption, OptionDescription, Config -from tiramisu_api import Config as JsonConfig +try: + from tiramisu_api import Config as JsonConfig + params = ['tiramisu', 'tiramisu-json'] +except: + params = ['tiramisu'] -@pytest.fixture(params=['tiramisu', 'tiramisu-json']) +@pytest.fixture(params=params) def json(request): return request.param diff --git a/tiramisu_cmdline_parser/__init__.py b/tiramisu_cmdline_parser/__init__.py index 2a5a6ac..88c1bd4 100644 --- a/tiramisu_cmdline_parser/__init__.py +++ b/tiramisu_cmdline_parser/__init__.py @@ -1,4 +1,4 @@ from .api import TiramisuCmdlineParser -__version__ = "0.3" +__version__ = "0.4" __all__ = ('TiramisuCmdlineParser',) diff --git a/tiramisu_cmdline_parser/api.py b/tiramisu_cmdline_parser/api.py index 85dfdde..51642c1 100644 --- a/tiramisu_cmdline_parser/api.py +++ b/tiramisu_cmdline_parser/api.py @@ -122,7 +122,7 @@ 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(["'{}'".format(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 @@ -135,7 +135,10 @@ class TiramisuNamespace(Namespace): value is not None and \ not isinstance(value, list): value = [value] - option.value.set(value) + try: + option.value.set(value) + except PropertiesOptionError: + raise AttributeError('unrecognized arguments: {}'.format(self.arguments[key])) def _setattr_follower(self, option: 'Option', @@ -275,21 +278,27 @@ class TiramisuCmdlineParser(ArgumentParser): remove_empty_od: bool=False, display_modified_value: bool=True, formatter_class=HelpFormatter, + unrestraint: bool=False, _forhelp: bool=False, **kwargs): self.fullpath = fullpath self.config = config self.root = root self.remove_empty_od = remove_empty_od + self.unrestraint = unrestraint self.display_modified_value = display_modified_value if TiramisuHelpFormatter not in formatter_class.__mro__: formatter_class = type('TiramisuHelpFormatter', (TiramisuHelpFormatter, formatter_class), {}) formatter_class.remove_empty_od = self.remove_empty_od kwargs['formatter_class'] = formatter_class - if self.root is None: - subconfig = self.config.option + if not _forhelp and self.unrestraint: + subconfig = self.config.unrestraint else: - subconfig = self.config.option(self.root) + subconfig = self.config + if self.root is None: + subconfig = subconfig.option + else: + subconfig = subconfig.option(self.root) self.namespace = TiramisuNamespace(self.config, self.root) super().__init__(*args, **kwargs) self.register('action', 'help', _TiramisuHelpAction) @@ -330,7 +339,7 @@ class TiramisuCmdlineParser(ArgumentParser): def _parse_known_args(self, args=None, namespace=None): try: namespace_, args_ = super()._parse_known_args(args, namespace) - except (ValueError, LeadershipError) as err: + except (ValueError, LeadershipError, AttributeError) as err: self.error(err) if args != args_ and args_ and args_[0].startswith(self.prefix_chars): # option that was disabled are no more disable @@ -343,6 +352,7 @@ class TiramisuCmdlineParser(ArgumentParser): formatter_class=self.formatter_class, epilog=self.epilog, description=self.description, + unrestraint=self.unrestraint, fullpath=self.fullpath) namespace_, args_ = new_parser._parse_known_args(args_, new_parser.namespace) else: @@ -444,8 +454,11 @@ class TiramisuCmdlineParser(ArgumentParser): leadership_len = len(value) elif option.isfollower(): value = [] - for index in range(leadership_len): - value.append(self.config.option(obj.option.path(), index).value.get()) + try: + for index in range(leadership_len): + value.append(self.config.option(obj.option.path(), index).value.get()) + except: + value = None else: value = obj.value.get() if self.fullpath and prefix: