From b3970475e7ec2deae1002b7900e9f4461d957503 Mon Sep 17 00:00:00 2001 From: Yann Kaiser Date: Sun, 9 Jul 2023 15:47:27 -0700 Subject: [PATCH] Improve error message when passing description= to run when not using multi-commands (#103) * Improve error message when passing description= to run when not using multi-commands * test it --- clize/runner.py | 33 +++++++++++++++++++++------------ clize/tests/test_runner.py | 7 +++++++ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/clize/runner.py b/clize/runner.py index 36966b2..95a5e88 100644 --- a/clize/runner.py +++ b/clize/runner.py @@ -64,7 +64,9 @@ def __new__(cls, fn=None, **kwargs): return super(Clize, cls).__new__(cls) def __init__(self, fn, owner=None, alt=(), extra=(), - help_names=('help', 'h'), helper_class=None, hide_help=False): + help_names=('help', 'h'), helper_class=None, hide_help=False, + description=None, + ): """ :param sequence alt: Alternate actions the CLI will handle. :param help_names: Names to use to trigger the help. @@ -75,6 +77,14 @@ def __init__(self, fn, owner=None, alt=(), extra=(), :param bool hide_help: Mark the parameters used to trigger the help as undocumented. """ + if description: + raise TypeError( + "description= is only accepted when using multiple same-level commands. " + "When only one main command is given, " + "you can set the description by updating the main command's docstring. See " + "https://clize.readthedocs.io/en/stable/basics.html#enhancing-the-help-message " + "for more information." + ) update_wrapper(self, fn) self.func = fn self.owner = owner @@ -169,18 +179,17 @@ class method is used from is used to build a CLI. ``**kwargs`` are the given object(s). """ try: - cli = obj.cli + return obj.cli except AttributeError: - if callable(obj): - cli = cls(obj, **kwargs) - else: - try: - iter(obj) - except TypeError: - raise TypeError("Don't know how to build a cli for " - + repr(obj)) - cli = SubcommandDispatcher(obj, **kwargs).cli - return cli + pass + if callable(obj): + return cls(obj, **kwargs) + else: + try: + iter(obj) + except TypeError: + raise TypeError(f"Don't know how to build a cli for {obj!r}") from None + return SubcommandDispatcher(obj, **kwargs).cli @property def cli(self): diff --git a/clize/tests/test_runner.py b/clize/tests/test_runner.py index 067a355..e80bac4 100644 --- a/clize/tests/test_runner.py +++ b/clize/tests/test_runner.py @@ -276,6 +276,13 @@ def func3(): raise NotImplementedError runner.SubcommandDispatcher)) self.assertEqual(set(sd.cmds_by_name), set(['2', '3'])) + def test_deny_description_on_single(self): + def base(): raise NotImplementedError + def alt(): raise NotImplementedError + with self.assertRaises(TypeError) as cm: + runner.Clize.get_cli(base, alt=alt, description="not allowed") + self.assertIn("only one main command", str(cm.exception)) + def test_as_is(self): def func(): raise NotImplementedError ru = runner.Clize.get_cli(runner.Clize.as_is(func))