From c96ca13955ccf3918015cf33ec6c2e449f01444f Mon Sep 17 00:00:00 2001 From: Rizky Arlin Date: Wed, 2 Aug 2023 06:46:06 +0800 Subject: [PATCH 01/11] Add hints support for checkboxes --- src/inquirer/questions.py | 5 ++++- src/inquirer/render/console/__init__.py | 8 ++++++++ src/inquirer/render/console/_checkbox.py | 7 +++++++ src/inquirer/render/console/base.py | 4 ++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/inquirer/questions.py b/src/inquirer/questions.py index e0253599..f4501ae8 100644 --- a/src/inquirer/questions.py +++ b/src/inquirer/questions.py @@ -42,6 +42,7 @@ def __init__( ignore=False, validate=True, show_default=False, + hints=None, other=False, ): self.name = name @@ -52,6 +53,7 @@ def __init__( self._validate = validate self.answers = {} self.show_default = show_default + self.hints = hints or [] self._other = other if self._other: @@ -164,6 +166,7 @@ def __init__( name, message="", choices=None, + hints=None, locked=None, default=None, ignore=False, @@ -173,7 +176,7 @@ def __init__( autocomplete=None, ): - super().__init__(name, message, choices, default, ignore, validate, other=other) + super().__init__(name, message, choices, default, ignore, validate, hints=hints, other=other) self.locked = locked self.carousel = carousel self.autocomplete = autocomplete diff --git a/src/inquirer/render/console/__init__.py b/src/inquirer/render/console/__init__.py index c5658023..c3c132eb 100644 --- a/src/inquirer/render/console/__init__.py +++ b/src/inquirer/render/console/__init__.py @@ -46,6 +46,7 @@ def _event_loop(self, render): self._print_status_bar(render) self._print_header(render) + self._print_hint(render) self._print_options(render) self._process_input(render) @@ -90,6 +91,13 @@ def _print_header(self, render): tq=self._theme.Question, ) + def _print_hint(self, render): + msg_template = ( + "{t.move_up}{t.clear_eol}{t.normal} {msg}" + ) + if render.hint: + self.print_str(f"\n {msg_template}", msg=render.hint, lf=not render.title_inline, tq=self._theme.Question) + def _process_input(self, render): try: ev = self._event_gen.next() diff --git a/src/inquirer/render/console/_checkbox.py b/src/inquirer/render/console/_checkbox.py index 93781122..106c7baf 100644 --- a/src/inquirer/render/console/_checkbox.py +++ b/src/inquirer/render/console/_checkbox.py @@ -14,6 +14,13 @@ def __init__(self, *args, **kwargs): self.selection = [k for (k, v) in enumerate(self.question.choices) if v in self.default_choices()] self.current = 0 + @property + def hint(self): + try: + return self.question.hints[self.current] + except IndexError: + return "" + def default_choices(self): default = self.question.default or [] return default + self.locked diff --git a/src/inquirer/render/console/base.py b/src/inquirer/render/console/base.py index cfe35cfc..2e0c42b0 100644 --- a/src/inquirer/render/console/base.py +++ b/src/inquirer/render/console/base.py @@ -26,6 +26,10 @@ def other_input(self): def get_header(self): return self.question.message + @property + def hint(self): + return "" + def get_current_value(self): return "" From 93f8992ac7aa18c2b7553d0ee675b4b7aab6d8cf Mon Sep 17 00:00:00 2001 From: Rizky Arlin Date: Mon, 21 Aug 2023 22:44:32 +0800 Subject: [PATCH 02/11] change hints to dict, add hints to List Question, add tests --- src/inquirer/questions.py | 5 +-- src/inquirer/render/console/_checkbox.py | 4 +-- src/inquirer/render/console/_list.py | 17 ++++++---- .../console_render/test_checkbox.py | 34 +++++++++++++++++++ tests/integration/console_render/test_list.py | 34 +++++++++++++++++++ 5 files changed, 84 insertions(+), 10 deletions(-) diff --git a/src/inquirer/questions.py b/src/inquirer/questions.py index f4501ae8..cdb11be3 100644 --- a/src/inquirer/questions.py +++ b/src/inquirer/questions.py @@ -53,7 +53,7 @@ def __init__( self._validate = validate self.answers = {} self.show_default = show_default - self.hints = hints or [] + self.hints = hints or {} self._other = other if self._other: @@ -145,6 +145,7 @@ def __init__( name, message="", choices=None, + hints=None, default=None, ignore=False, validate=True, @@ -153,7 +154,7 @@ def __init__( autocomplete=None, ): - super().__init__(name, message, choices, default, ignore, validate, other=other) + super().__init__(name, message, choices, default, ignore, validate, hints=hints, other=other) self.carousel = carousel self.autocomplete = autocomplete diff --git a/src/inquirer/render/console/_checkbox.py b/src/inquirer/render/console/_checkbox.py index 106c7baf..8329f056 100644 --- a/src/inquirer/render/console/_checkbox.py +++ b/src/inquirer/render/console/_checkbox.py @@ -17,8 +17,8 @@ def __init__(self, *args, **kwargs): @property def hint(self): try: - return self.question.hints[self.current] - except IndexError: + return self.question.hints[self.question.choices[self.current]] + except KeyError: return "" def default_choices(self): diff --git a/src/inquirer/render/console/_list.py b/src/inquirer/render/console/_list.py index 49dcefc2..75b19d58 100644 --- a/src/inquirer/render/console/_list.py +++ b/src/inquirer/render/console/_list.py @@ -16,6 +16,17 @@ def __init__(self, *args, **kwargs): def is_long(self): choices = self.question.choices or [] return len(choices) >= MAX_OPTIONS_DISPLAYED_AT_ONCE + + @property + def hint(self): + try: + choice = self.question.choices[self.current] + hint = self.question.hints[choice] + return f"{choice}: {hint}" + except KeyError: + return "" + except IndexError: + return "" def get_options(self): choices = self.question.choices or [] @@ -88,9 +99,3 @@ def _current_index(self): return self.question.choices.index(self.question.default) except ValueError: return 0 - - def get_current_value(self): - try: - return self.question.choices[self.current] - except IndexError: - return "" diff --git a/tests/integration/console_render/test_checkbox.py b/tests/integration/console_render/test_checkbox.py index 2414e140..80bae4a0 100644 --- a/tests/integration/console_render/test_checkbox.py +++ b/tests/integration/console_render/test_checkbox.py @@ -394,3 +394,37 @@ def test_locked_with_default(self): result = sut.render(question) assert result == ["bar"] + + def test_first_hint_is_shown(self): + stdin = helper.event_factory(key.ENTER) + message = "Foo message" + variable = "Bar variable" + choices = { + "foo": "Foo", + "bar": "Bar", + "bazz": "Bazz", + } + + question = questions.Checkbox(variable, message, choices=choices.keys(), hints=choices) + + sut = ConsoleRender(event_generator=stdin) + sut.render(question) + + self.assertInStdout("Foo") + + def test_second_hint_is_shown(self): + stdin = helper.event_factory(key.DOWN, key.ENTER) + message = "Foo message" + variable = "Bar variable" + choices = { + "foo": "Foo", + "bar": "Bar", + "bazz": "Bazz", + } + + question = questions.Checkbox(variable, message, choices=choices.keys(), hints=choices) + + sut = ConsoleRender(event_generator=stdin) + sut.render(question) + + self.assertInStdout("Bar") diff --git a/tests/integration/console_render/test_list.py b/tests/integration/console_render/test_list.py index 5e92e5f6..174e5b96 100644 --- a/tests/integration/console_render/test_list.py +++ b/tests/integration/console_render/test_list.py @@ -131,3 +131,37 @@ def test_ctrl_c_breaks_execution(self): sut = ConsoleRender(event_generator=stdin) with pytest.raises(KeyboardInterrupt): sut.render(question) + + def test_first_hint_is_shown(self): + stdin = helper.event_factory(key.ENTER) + message = "Foo message" + variable = "Bar variable" + choices = { + "foo": "Foo", + "bar": "Bar", + "bazz": "Bazz", + } + + question = questions.List(variable, message, choices=choices.keys(), hints=choices) + + sut = ConsoleRender(event_generator=stdin) + sut.render(question) + + self.assertInStdout("Foo") + + def test_second_hint_is_shown(self): + stdin = helper.event_factory(key.DOWN, key.ENTER) + message = "Foo message" + variable = "Bar variable" + choices = { + "foo": "Foo", + "bar": "Bar", + "bazz": "Bazz", + } + + question = questions.List(variable, message, choices=choices.keys(), hints=choices) + + sut = ConsoleRender(event_generator=stdin) + sut.render(question) + + self.assertInStdout("Bar") From 6973d62688fb7a884ac7cff583422fe1d762b3df Mon Sep 17 00:00:00 2001 From: Rizky Arlin Date: Tue, 22 Aug 2023 00:31:01 +0800 Subject: [PATCH 03/11] Handle empty string and None for hints, add color for hints, & Update Docs --- docs/usage.md | 15 +++++++++++++++ src/inquirer/render/console/__init__.py | 7 ++++--- src/inquirer/render/console/_checkbox.py | 11 +++++++---- src/inquirer/render/console/_list.py | 12 +++++++----- src/inquirer/render/console/base.py | 5 ++--- 5 files changed, 35 insertions(+), 15 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 9ee3aaae..ce74d760 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -115,6 +115,21 @@ If any of the list values is a pair, it should be a tuple like: `(label, value)` As before, the `answers` is a `dict` containing the previous answers. +### hints +**Optional** for `Checkbox` and `List` questions; the rest of them do not have hints. + +The hint for the selected choice will be shown above the first choice. + +```python +from inquirer import questions +choices = { + "foo": "Foo", + "bar": "Bar", + "bazz": "Bazz", +} +question = questions.Checkbox("foo", "Choose one:", choices=choices.keys(), hints=choices) +``` + ### validate Optional attribute that allows the program to check if the answer is valid or not. It requires a `boolean` value or a `function` with the sign: diff --git a/src/inquirer/render/console/__init__.py b/src/inquirer/render/console/__init__.py index c3c132eb..7d867fb7 100644 --- a/src/inquirer/render/console/__init__.py +++ b/src/inquirer/render/console/__init__.py @@ -93,10 +93,11 @@ def _print_header(self, render): def _print_hint(self, render): msg_template = ( - "{t.move_up}{t.clear_eol}{t.normal} {msg}" + "{t.move_up}{t.clear_eol}{color} {msg}" ) - if render.hint: - self.print_str(f"\n {msg_template}", msg=render.hint, lf=not render.title_inline, tq=self._theme.Question) + hint, color = render.get_hint() + if hint: + self.print_str(f"\n {msg_template}", msg=hint, color=color, lf=not render.title_inline, tq=self._theme.Question) def _process_input(self, render): try: diff --git a/src/inquirer/render/console/_checkbox.py b/src/inquirer/render/console/_checkbox.py index 8329f056..dceef38b 100644 --- a/src/inquirer/render/console/_checkbox.py +++ b/src/inquirer/render/console/_checkbox.py @@ -14,12 +14,15 @@ def __init__(self, *args, **kwargs): self.selection = [k for (k, v) in enumerate(self.question.choices) if v in self.default_choices()] self.current = 0 - @property - def hint(self): + def get_hint(self): try: - return self.question.hints[self.question.choices[self.current]] + hint = self.question.hints[self.question.choices[self.current]] + if hint: + return hint, self.theme.Checkbox.selection_color + else : + return "\r", "" except KeyError: - return "" + return "\r", "" def default_choices(self): default = self.question.default or [] diff --git a/src/inquirer/render/console/_list.py b/src/inquirer/render/console/_list.py index 75b19d58..33fedb89 100644 --- a/src/inquirer/render/console/_list.py +++ b/src/inquirer/render/console/_list.py @@ -17,16 +17,18 @@ def is_long(self): choices = self.question.choices or [] return len(choices) >= MAX_OPTIONS_DISPLAYED_AT_ONCE - @property - def hint(self): + def get_hint(self): try: choice = self.question.choices[self.current] hint = self.question.hints[choice] - return f"{choice}: {hint}" + if hint: + return f"{choice}: {hint}", self.theme.List.selection_color + else: + return f"{choice}", self.theme.List.selection_color except KeyError: - return "" + return "\r", "" except IndexError: - return "" + return "\r", "" def get_options(self): choices = self.question.choices or [] diff --git a/src/inquirer/render/console/base.py b/src/inquirer/render/console/base.py index 2e0c42b0..0ca7ed91 100644 --- a/src/inquirer/render/console/base.py +++ b/src/inquirer/render/console/base.py @@ -26,9 +26,8 @@ def other_input(self): def get_header(self): return self.question.message - @property - def hint(self): - return "" + def get_hint(self): + return "", "" def get_current_value(self): return "" From a5f84d033231b6b9c591f5485d43431575bebc53 Mon Sep 17 00:00:00 2001 From: Jan Wille Date: Mon, 8 Jan 2024 10:07:14 +0100 Subject: [PATCH 04/11] remove random whitespace --- src/inquirer/render/console/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/inquirer/render/console/__init__.py b/src/inquirer/render/console/__init__.py index 7d867fb7..3e6133a1 100644 --- a/src/inquirer/render/console/__init__.py +++ b/src/inquirer/render/console/__init__.py @@ -93,11 +93,11 @@ def _print_header(self, render): def _print_hint(self, render): msg_template = ( - "{t.move_up}{t.clear_eol}{color} {msg}" + "{t.move_up}{t.clear_eol}{color}{msg}" ) hint, color = render.get_hint() if hint: - self.print_str(f"\n {msg_template}", msg=hint, color=color, lf=not render.title_inline, tq=self._theme.Question) + self.print_str(f"\n{msg_template}", msg=hint, color=color, lf=not render.title_inline, tq=self._theme.Question) def _process_input(self, render): try: From f3e982a2e6b4f8f306161b9b96157ed9b25d9282 Mon Sep 17 00:00:00 2001 From: Jan Wille Date: Mon, 8 Jan 2024 10:07:46 +0100 Subject: [PATCH 05/11] example showing hints --- examples/checkbox_hints.py | 21 +++++++++++++++++++++ examples/list_hints.py | 19 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 examples/checkbox_hints.py create mode 100644 examples/list_hints.py diff --git a/examples/checkbox_hints.py b/examples/checkbox_hints.py new file mode 100644 index 00000000..591c1e1d --- /dev/null +++ b/examples/checkbox_hints.py @@ -0,0 +1,21 @@ +from pprint import pprint + +import inquirer # noqa + + +choices_hints = { + "Computers": "The really Geeky stuff", + "Books": "Its just so cosy", + "Science": "I want to know it all", + "Nature": "Always outdoors", +} + +questions = [ + inquirer.Checkbox( + "interests", message="What are you interested in?", choices=choices_hints.keys(), hints=choices_hints + ), +] + +answers = inquirer.prompt(questions) + +pprint(answers) diff --git a/examples/list_hints.py b/examples/list_hints.py new file mode 100644 index 00000000..1bafb6f1 --- /dev/null +++ b/examples/list_hints.py @@ -0,0 +1,19 @@ +from pprint import pprint + +import inquirer # noqa + +choices_hints = { + "Jumbo": "The biggest one we have", + "Large": "If you need the extra kick", + "Standard": "For your every day use", +} + +questions = [ + inquirer.List( + "size", message="What size do you need?", choices=choices_hints.keys(), hints=choices_hints + ), +] + +answers = inquirer.prompt(questions) + +pprint(answers) From 2336b75b2fba12fe91497b3835de319482883c74 Mon Sep 17 00:00:00 2001 From: Jan Wille Date: Mon, 8 Jan 2024 10:19:36 +0100 Subject: [PATCH 06/11] move theming into printing function --- src/inquirer/render/console/__init__.py | 3 ++- src/inquirer/render/console/_checkbox.py | 6 +++--- src/inquirer/render/console/_list.py | 10 +++++----- src/inquirer/render/console/base.py | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/inquirer/render/console/__init__.py b/src/inquirer/render/console/__init__.py index 3e6133a1..0ae317ca 100644 --- a/src/inquirer/render/console/__init__.py +++ b/src/inquirer/render/console/__init__.py @@ -95,7 +95,8 @@ def _print_hint(self, render): msg_template = ( "{t.move_up}{t.clear_eol}{color}{msg}" ) - hint, color = render.get_hint() + hint = render.get_hint() + color = self._theme.Question.mark_color if hint: self.print_str(f"\n{msg_template}", msg=hint, color=color, lf=not render.title_inline, tq=self._theme.Question) diff --git a/src/inquirer/render/console/_checkbox.py b/src/inquirer/render/console/_checkbox.py index dceef38b..ca566f5b 100644 --- a/src/inquirer/render/console/_checkbox.py +++ b/src/inquirer/render/console/_checkbox.py @@ -18,11 +18,11 @@ def get_hint(self): try: hint = self.question.hints[self.question.choices[self.current]] if hint: - return hint, self.theme.Checkbox.selection_color + return hint else : - return "\r", "" + return "\r" except KeyError: - return "\r", "" + return "\r" def default_choices(self): default = self.question.default or [] diff --git a/src/inquirer/render/console/_list.py b/src/inquirer/render/console/_list.py index 33fedb89..9ab55bb8 100644 --- a/src/inquirer/render/console/_list.py +++ b/src/inquirer/render/console/_list.py @@ -16,19 +16,19 @@ def __init__(self, *args, **kwargs): def is_long(self): choices = self.question.choices or [] return len(choices) >= MAX_OPTIONS_DISPLAYED_AT_ONCE - + def get_hint(self): try: choice = self.question.choices[self.current] hint = self.question.hints[choice] if hint: - return f"{choice}: {hint}", self.theme.List.selection_color + return f"{choice}: {hint}" else: - return f"{choice}", self.theme.List.selection_color + return f"{choice}" except KeyError: - return "\r", "" + return "\r" except IndexError: - return "\r", "" + return "\r" def get_options(self): choices = self.question.choices or [] diff --git a/src/inquirer/render/console/base.py b/src/inquirer/render/console/base.py index 0ca7ed91..950d83ab 100644 --- a/src/inquirer/render/console/base.py +++ b/src/inquirer/render/console/base.py @@ -27,7 +27,7 @@ def get_header(self): return self.question.message def get_hint(self): - return "", "" + return "" def get_current_value(self): return "" From 1e6fb6cbd3ad84f5b62423d2f510300ccff1574f Mon Sep 17 00:00:00 2001 From: Jan Wille Date: Mon, 8 Jan 2024 10:30:38 +0100 Subject: [PATCH 07/11] remove redundant `\r` from returns --- src/inquirer/render/console/_checkbox.py | 4 ++-- src/inquirer/render/console/_list.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/inquirer/render/console/_checkbox.py b/src/inquirer/render/console/_checkbox.py index ca566f5b..99e543be 100644 --- a/src/inquirer/render/console/_checkbox.py +++ b/src/inquirer/render/console/_checkbox.py @@ -20,9 +20,9 @@ def get_hint(self): if hint: return hint else : - return "\r" + return "" except KeyError: - return "\r" + return "" def default_choices(self): default = self.question.default or [] diff --git a/src/inquirer/render/console/_list.py b/src/inquirer/render/console/_list.py index 9ab55bb8..ccae95a5 100644 --- a/src/inquirer/render/console/_list.py +++ b/src/inquirer/render/console/_list.py @@ -26,9 +26,9 @@ def get_hint(self): else: return f"{choice}" except KeyError: - return "\r" + return "" except IndexError: - return "\r" + return "" def get_options(self): choices = self.question.choices or [] From ef8698d37de8f45256e4cf46bc35e6f58c4cbee2 Mon Sep 17 00:00:00 2001 From: Jan Wille Date: Mon, 8 Jan 2024 11:01:05 +0100 Subject: [PATCH 08/11] make `TaggedValues` work as dict-key that makes them usable identically as the original tuple they where constructed from --- examples/checkbox_hints.py | 8 ++++---- src/inquirer/questions.py | 16 ++++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/examples/checkbox_hints.py b/examples/checkbox_hints.py index 591c1e1d..0c0a40d8 100644 --- a/examples/checkbox_hints.py +++ b/examples/checkbox_hints.py @@ -4,10 +4,10 @@ choices_hints = { - "Computers": "The really Geeky stuff", - "Books": "Its just so cosy", - "Science": "I want to know it all", - "Nature": "Always outdoors", + ("Computers", 'c'): "The really Geeky stuff", + ("Books", 'b'): "Its just so cosy", + ("Science", 's'): "I want to know it all", + ("Nature", 'n'): "Always outdoors", } questions = [ diff --git a/src/inquirer/questions.py b/src/inquirer/questions.py index cdb11be3..b238f363 100644 --- a/src/inquirer/questions.py +++ b/src/inquirer/questions.py @@ -11,9 +11,10 @@ class TaggedValue: - def __init__(self, label, value): - self.label = label - self.value = value + def __init__(self, choice): + self.label = choice[0] + self.value = choice[1] + self._hash = hash(choice) def __str__(self): return self.label @@ -24,11 +25,16 @@ def __repr__(self): def __eq__(self, other): if isinstance(other, TaggedValue): return self.value == other.value + if isinstance(other, tuple): + return self.label, self.value == other return self.value == other def __ne__(self, other): return not self.__eq__(other) + def __hash__(self) -> int: + return self._hash + class Question: kind = "base question" @@ -86,7 +92,7 @@ def default(self): @property def choices_generator(self): for choice in self._solve(self._choices): - yield (TaggedValue(*choice) if isinstance(choice, tuple) and len(choice) == 2 else choice) + yield (TaggedValue(choice) if isinstance(choice, tuple) and len(choice) == 2 else choice) @property def choices(self): @@ -153,7 +159,6 @@ def __init__( other=False, autocomplete=None, ): - super().__init__(name, message, choices, default, ignore, validate, hints=hints, other=other) self.carousel = carousel self.autocomplete = autocomplete @@ -176,7 +181,6 @@ def __init__( other=False, autocomplete=None, ): - super().__init__(name, message, choices, default, ignore, validate, hints=hints, other=other) self.locked = locked self.carousel = carousel From 5ef0bed9b29a36178d19668c23a24cebe5055cfd Mon Sep 17 00:00:00 2001 From: Jan Wille Date: Mon, 8 Jan 2024 11:05:00 +0100 Subject: [PATCH 09/11] simplify return logic and duplicate error handlers --- src/inquirer/render/console/_checkbox.py | 5 +---- src/inquirer/render/console/_list.py | 4 +--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/inquirer/render/console/_checkbox.py b/src/inquirer/render/console/_checkbox.py index 99e543be..6e40c5bd 100644 --- a/src/inquirer/render/console/_checkbox.py +++ b/src/inquirer/render/console/_checkbox.py @@ -17,10 +17,7 @@ def __init__(self, *args, **kwargs): def get_hint(self): try: hint = self.question.hints[self.question.choices[self.current]] - if hint: - return hint - else : - return "" + return hint or "" except KeyError: return "" diff --git a/src/inquirer/render/console/_list.py b/src/inquirer/render/console/_list.py index ccae95a5..1fe19c4a 100644 --- a/src/inquirer/render/console/_list.py +++ b/src/inquirer/render/console/_list.py @@ -25,9 +25,7 @@ def get_hint(self): return f"{choice}: {hint}" else: return f"{choice}" - except KeyError: - return "" - except IndexError: + except (KeyError, IndexError): return "" def get_options(self): From 11d575f3ebc5e0b85f8d301ffe9ebbc1a1a4502d Mon Sep 17 00:00:00 2001 From: Jan Wille Date: Mon, 8 Jan 2024 11:12:32 +0100 Subject: [PATCH 10/11] run `pre-commit` --- docs/usage.md | 1 + examples/checkbox_hints.py | 8 ++++---- examples/list_hints.py | 12 +++++------- src/inquirer/render/console/__init__.py | 8 ++++---- tests/integration/console_render/test_checkbox.py | 4 ++-- tests/integration/console_render/test_list.py | 4 ++-- 6 files changed, 18 insertions(+), 19 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 04b197cf..f65ed0e5 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -118,6 +118,7 @@ If any of the list values is a pair, it should be a tuple like: `(label, value)` As before, the `answers` is a `dict` containing the previous answers. ### hints + **Optional** for `Checkbox` and `List` questions; the rest of them do not have hints. The hint for the selected choice will be shown above the first choice. diff --git a/examples/checkbox_hints.py b/examples/checkbox_hints.py index 0c0a40d8..879d583a 100644 --- a/examples/checkbox_hints.py +++ b/examples/checkbox_hints.py @@ -4,10 +4,10 @@ choices_hints = { - ("Computers", 'c'): "The really Geeky stuff", - ("Books", 'b'): "Its just so cosy", - ("Science", 's'): "I want to know it all", - ("Nature", 'n'): "Always outdoors", + ("Computers", "c"): "The really Geeky stuff", + ("Books", "b"): "Its just so cosy", + ("Science", "s"): "I want to know it all", + ("Nature", "n"): "Always outdoors", } questions = [ diff --git a/examples/list_hints.py b/examples/list_hints.py index 1bafb6f1..b2877ea8 100644 --- a/examples/list_hints.py +++ b/examples/list_hints.py @@ -2,16 +2,14 @@ import inquirer # noqa -choices_hints = { - "Jumbo": "The biggest one we have", - "Large": "If you need the extra kick", - "Standard": "For your every day use", +choices_hints = { + "Jumbo": "The biggest one we have", + "Large": "If you need the extra kick", + "Standard": "For your every day use", } questions = [ - inquirer.List( - "size", message="What size do you need?", choices=choices_hints.keys(), hints=choices_hints - ), + inquirer.List("size", message="What size do you need?", choices=choices_hints.keys(), hints=choices_hints), ] answers = inquirer.prompt(questions) diff --git a/src/inquirer/render/console/__init__.py b/src/inquirer/render/console/__init__.py index 0ae317ca..7e0d84d2 100644 --- a/src/inquirer/render/console/__init__.py +++ b/src/inquirer/render/console/__init__.py @@ -92,13 +92,13 @@ def _print_header(self, render): ) def _print_hint(self, render): - msg_template = ( - "{t.move_up}{t.clear_eol}{color}{msg}" - ) + msg_template = "{t.move_up}{t.clear_eol}{color}{msg}" hint = render.get_hint() color = self._theme.Question.mark_color if hint: - self.print_str(f"\n{msg_template}", msg=hint, color=color, lf=not render.title_inline, tq=self._theme.Question) + self.print_str( + f"\n{msg_template}", msg=hint, color=color, lf=not render.title_inline, tq=self._theme.Question + ) def _process_input(self, render): try: diff --git a/tests/integration/console_render/test_checkbox.py b/tests/integration/console_render/test_checkbox.py index 80bae4a0..f1531971 100644 --- a/tests/integration/console_render/test_checkbox.py +++ b/tests/integration/console_render/test_checkbox.py @@ -404,7 +404,7 @@ def test_first_hint_is_shown(self): "bar": "Bar", "bazz": "Bazz", } - + question = questions.Checkbox(variable, message, choices=choices.keys(), hints=choices) sut = ConsoleRender(event_generator=stdin) @@ -421,7 +421,7 @@ def test_second_hint_is_shown(self): "bar": "Bar", "bazz": "Bazz", } - + question = questions.Checkbox(variable, message, choices=choices.keys(), hints=choices) sut = ConsoleRender(event_generator=stdin) diff --git a/tests/integration/console_render/test_list.py b/tests/integration/console_render/test_list.py index 174e5b96..c4b2e747 100644 --- a/tests/integration/console_render/test_list.py +++ b/tests/integration/console_render/test_list.py @@ -141,7 +141,7 @@ def test_first_hint_is_shown(self): "bar": "Bar", "bazz": "Bazz", } - + question = questions.List(variable, message, choices=choices.keys(), hints=choices) sut = ConsoleRender(event_generator=stdin) @@ -158,7 +158,7 @@ def test_second_hint_is_shown(self): "bar": "Bar", "bazz": "Bazz", } - + question = questions.List(variable, message, choices=choices.keys(), hints=choices) sut = ConsoleRender(event_generator=stdin) From d0155e582e1714b08207afa2ea38624037f599e0 Mon Sep 17 00:00:00 2001 From: Jan Wille Date: Mon, 8 Jan 2024 11:25:49 +0100 Subject: [PATCH 11/11] fix test for `TaggedValue` --- src/inquirer/questions.py | 10 +++++----- tests/unit/test_question.py | 21 ++++++++++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/inquirer/questions.py b/src/inquirer/questions.py index b238f363..8dbbffea 100644 --- a/src/inquirer/questions.py +++ b/src/inquirer/questions.py @@ -13,21 +13,21 @@ class TaggedValue: def __init__(self, choice): self.label = choice[0] - self.value = choice[1] + self.tag = choice[1] self._hash = hash(choice) def __str__(self): return self.label def __repr__(self): - return self.value + return repr(self.tag) def __eq__(self, other): if isinstance(other, TaggedValue): - return self.value == other.value + return other.tag == self.tag if isinstance(other, tuple): - return self.label, self.value == other - return self.value == other + return other == (self.label, self.tag) + return other == self.tag def __ne__(self, other): return not self.__eq__(other) diff --git a/tests/unit/test_question.py b/tests/unit/test_question.py index 618d55f5..9c9bdc8d 100644 --- a/tests/unit/test_question.py +++ b/tests/unit/test_question.py @@ -353,10 +353,17 @@ def test_default_value_validation(self): def test_tagged_value(): - tv = questions.TaggedValue("label", "value") - - assert tv.__str__() == "label" - assert tv.__repr__() == "value" - assert tv.__eq__(tv) is True - assert tv.__eq__("") is False - assert tv.__ne__(tv) is False + LABEL = "label" + TAG = "l" + tp = (LABEL, TAG) + tv = questions.TaggedValue(tp) + + assert (str(tv) == str(LABEL)) is True + assert (repr(tv) == repr(TAG)) is True + assert (hash(tv) == hash(tp)) is True + + assert (tv == tv) is True + assert (tv != tv) is False + assert (tv == tp) is True + assert (tv == TAG) is True + assert (tv == "") is False