Compare commits

..

No commits in common. "main" and "0.7.0a6" have entirely different histories.

5 changed files with 70 additions and 128 deletions

View file

@ -1,24 +1,65 @@
## 1.0.0 (2026-06-21) ## 0.7.0a6 (2026-06-11)
### Feat ### Feat
- allow undefined option - allow undefined option
## 0.7.0a5 (2025-12-30)
## 0.7.0a4 (2025-11-21)
### Feat
- add 'add_help' option un TiramisuCmdLineParser - add 'add_help' option un TiramisuCmdLineParser
## 0.7.0a3 (2025-10-10)
### Feat
- do not exit() with exit_on_error to False - do not exit() with exit_on_error to False
### Fix
- update test
## 0.7.0a2 (2025-09-29)
### Fix
- better support for boolean help
## 0.7.0a1 (2025-05-12)
### Fix
- black
## 0.7.0a0 (2025-04-30)
### Feat
- for boolean always add --xxx and --no-xxx - for boolean always add --xxx and --no-xxx
### Fix ### Fix
- tiramisu dependencies
- black
- remove prog and description attribute
- support exit_on_error
- update test
- better support for boolean help
- black
- formatter.short_name_max_len for symlink - formatter.short_name_max_len for symlink
## 0.6.2rc2 (2025-04-09)
### Fix
- version - version
## 0.6.2rc1 (2025-03-19)
### Fix
- better leader support - better leader support
## 0.6.2rc0 (2025-01-03)
### Fix
- python 2.12 support - python 2.12 support
## 0.6.1 (2024-11-06) ## 0.6.1 (2024-11-06)

View file

@ -4,7 +4,7 @@ requires = ["flit_core >=3.8.0,<4"]
[project] [project]
name = "tiramisu_cmdline_parser" name = "tiramisu_cmdline_parser"
version = "1.0.0" version = "0.7.0a6"
authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}] authors = [{name = "Emmanuel Garette", email = "gnunux@gnunux.info"}]
readme = "README.md" readme = "README.md"
description = "command-line parser using Tiramisu" description = "command-line parser using Tiramisu"
@ -28,7 +28,7 @@ classifiers = [
] ]
dependencies = [ dependencies = [
"tiramisu > 5.1,<6", "tiramisu >= 5.0,<6",
] ]
[project.urls] [project.urls]

View file

@ -1,85 +0,0 @@
import pytest
from argparse import ArgumentError
from tiramisu_cmdline_parser import TiramisuCmdlineParser
from tiramisu import StrOption, BoolOption, OptionDescription, Config
from .utils import TestHelpFormatter
def get_config(has_tree=False, default_verbosity=False):
booloption = BoolOption('disabled',
'disabled',
properties=('disabled',),
)
booloption2 = BoolOption('verbosity',
'increase output verbosity',
default=default_verbosity,
)
stroption = StrOption('option',
'an option',
)
root = OptionDescription('root',
'root',
[booloption, booloption2, stroption],
)
if has_tree:
root = OptionDescription('root',
'root',
[root],
)
config = Config(root)
config.property.read_write()
return config
def test_exit_boolean():
config = get_config(default_verbosity=True)
parser = TiramisuCmdlineParser(config, 'prog.py', formatter_class=TestHelpFormatter, color=False, exit_on_error=False)
parser.parse_args(['--verbosity'])
parser.parse_known_args(['--verbosity'])
def test_exit_disabled():
config = get_config(default_verbosity=True)
parser = TiramisuCmdlineParser(config, 'prog.py', formatter_class=TestHelpFormatter, color=False, exit_on_error=False)
error = None
try:
parser.parse_args(['--disabled'])
except ArgumentError as err:
error = err
assert error
assert str(error) == 'unrecognized arguments: --disabled (cannot access to option "disabled" because has property "disabled")'
def test_exit_string():
config = get_config(default_verbosity=True)
parser = TiramisuCmdlineParser(config, 'prog.py', formatter_class=TestHelpFormatter, color=False, exit_on_error=False)
parser.parse_args(['--option', 'value'])
parser.parse_known_args(['--option', 'value'])
def test_exit_unknown():
config = get_config(default_verbosity=True)
parser = TiramisuCmdlineParser(config, 'prog.py', formatter_class=TestHelpFormatter, color=False, exit_on_error=False)
error = None
try:
parser.parse_args(['--unknown', 'value'])
except ArgumentError as err:
error = err
assert error
assert str(error) == 'unrecognized arguments: --unknown value'
parser.parse_known_args(['--unknown', 'value'])
def test_exit_known_unknown():
config = get_config(default_verbosity=True)
parser = TiramisuCmdlineParser(config, 'prog.py', formatter_class=TestHelpFormatter, color=False, exit_on_error=False)
error = None
try:
parser.parse_args(['--option', 'value', '--unknown', 'value'])
except ArgumentError as err:
error = err
assert error
assert str(error) == 'unrecognized arguments: --unknown value'
parser.parse_known_args(['--unknown', 'value'])

View file

@ -1 +1 @@
__version__ = "1.0.0" __version__ = "0.7.0a6"

View file

@ -27,12 +27,7 @@ from gettext import gettext as _
# try: # try:
from tiramisu import Config from tiramisu import Config
from tiramisu.error import ( from tiramisu.error import PropertiesOptionError, LeadershipError, ConfigError, AttributeOptionError
PropertiesOptionError,
LeadershipError,
ConfigError,
AttributeOptionError,
)
def get_choice_list(config, properties, display): def get_choice_list(config, properties, display):
@ -332,7 +327,6 @@ class TiramisuCmdlineParser(ArgumentParser):
add_extra_options: bool = True, add_extra_options: bool = True,
short_name_max_len: int = 1, short_name_max_len: int = 1,
add_help: bool = True, add_help: bool = True,
exit_on_error: bool = True,
_forhelp: bool = False, _forhelp: bool = False,
**kwargs, **kwargs,
): ):
@ -341,9 +335,7 @@ class TiramisuCmdlineParser(ArgumentParser):
self.fullpath = fullpath self.fullpath = fullpath
self.config = config self.config = config
config_properties = config.property.get() config_properties = config.property.get()
self.config_frozen = ( self.config_frozen = "frozen" in config_properties or "everything_frozen" in config_properties
"frozen" in config_properties or "everything_frozen" in config_properties
)
self.root = root self.root = root
self.remove_empty_od = remove_empty_od self.remove_empty_od = remove_empty_od
self.unrestraint = unrestraint self.unrestraint = unrestraint
@ -368,9 +360,7 @@ class TiramisuCmdlineParser(ArgumentParser):
else: else:
subconfig = subconfig.option(self.root) subconfig = subconfig.option(self.root)
self.namespace = TiramisuNamespace(self.config, self.root) self.namespace = TiramisuNamespace(self.config, self.root)
super().__init__( super().__init__(*args, add_help=add_help, **kwargs)
*args, add_help=add_help, exit_on_error=exit_on_error, **kwargs
)
self.register("action", "help", _TiramisuHelpAction) self.register("action", "help", _TiramisuHelpAction)
self._config_to_argparser( self._config_to_argparser(
_forhelp, _forhelp,
@ -412,7 +402,10 @@ class TiramisuCmdlineParser(ArgumentParser):
except (ValueError, LeadershipError, AttributeError) as err: except (ValueError, LeadershipError, AttributeError) as err:
self.error(err) self.error(err)
if args != args_ and args_ and args_[0].startswith(self.prefix_chars): if args != args_ and args_ and args_[0].startswith(self.prefix_chars):
kwargs = self.clean_kwargs() kwargs = self.kwargs
if "epilog" in kwargs:
kwargs = kwargs.copy()
del kwargs["epilog"]
# option that was disabled are no more disable # option that was disabled are no more disable
# so create a new parser # so create a new parser
new_parser = TiramisuCmdlineParser( new_parser = TiramisuCmdlineParser(
@ -701,11 +694,7 @@ class TiramisuCmdlineParser(ArgumentParser):
kwargs["type"] = float kwargs["type"] = float
else: else:
pass pass
if ( if not _forhelp and option.type() != "boolean" and "nargs" not in kwargs.kwargs:
not _forhelp
and option.type() != "boolean"
and "nargs" not in kwargs.kwargs
):
kwargs["nargs"] = "?" kwargs["nargs"] = "?"
actions.setdefault(kwargs.ga_name, []).append(kwargs) actions.setdefault(kwargs.ga_name, []).append(kwargs)
@ -718,11 +707,9 @@ class TiramisuCmdlineParser(ArgumentParser):
group.add_argument(*args, **kwargs) group.add_argument(*args, **kwargs)
def parse_args(self, *args, valid_mandatory=True, **kwargs): def parse_args(self, *args, valid_mandatory=True, **kwargs):
namespaces, unknown = self.parse_known_args( namespaces, unknown = self.parse_known_args(*args, valid_mandatory=valid_mandatory, **kwargs)
*args, valid_mandatory=valid_mandatory, **kwargs
)
if unknown: if unknown:
msg_unknown = "unrecognized arguments: %s" % " ".join(unknown) msg_unknown = 'unrecognized arguments: %s' % ' '.join(unknown)
if self.exit_on_error: if self.exit_on_error:
self.error(msg_unknown) self.error(msg_unknown)
else: else:
@ -780,7 +767,10 @@ class TiramisuCmdlineParser(ArgumentParser):
return namespaces, unknown return namespaces, unknown
def format_usage(self, *args, **kwargs): def format_usage(self, *args, **kwargs):
kwargs_ = self.clean_kwargs() kwargs_ = self.kwargs
if "epilog" in kwargs_:
kwargs_ = kwargs_.copy()
del kwargs_["epilog"]
help_formatter = TiramisuCmdlineParser( help_formatter = TiramisuCmdlineParser(
self.config, self.config,
self.prog, self.prog,
@ -801,7 +791,10 @@ class TiramisuCmdlineParser(ArgumentParser):
) )
def format_help(self): def format_help(self):
kwargs = self.clean_kwargs() kwargs = self.kwargs
if "epilog" in kwargs:
kwargs = kwargs.copy()
del kwargs["epilog"]
help_formatter = TiramisuCmdlineParser( help_formatter = TiramisuCmdlineParser(
self.config, self.config,
self.prog, self.prog,
@ -827,10 +820,3 @@ class TiramisuCmdlineParser(ArgumentParser):
super().error(msg) super().error(msg)
else: else:
raise ArgumentError(None, msg) raise ArgumentError(None, msg)
def clean_kwargs(self):
kwargs = self.kwargs.copy()
for arg in ["epilog", "prog", "description"]:
if arg in kwargs:
del kwargs[arg]
return kwargs