diff options
-rw-r--r-- | cmd2/argparse_completer.py | 7 | ||||
-rw-r--r-- | tests/test_argparse_completer.py | 19 |
2 files changed, 24 insertions, 2 deletions
diff --git a/cmd2/argparse_completer.py b/cmd2/argparse_completer.py index 21007289..ef35eabc 100644 --- a/cmd2/argparse_completer.py +++ b/cmd2/argparse_completer.py @@ -641,8 +641,11 @@ class ArgparseCompleter: arg_choices.sort() self._cmd2_app.matches_sorted = True - # Since choices can be various types, convert them all to strings - arg_choices = [str(x) for x in arg_choices] + # Since choices can be various types, make sure they are all strings + for index, choice in enumerate(arg_choices): + # Prevent converting anything that is already a str (i.e. CompletionItem) + if not isinstance(choice, str): + arg_choices[index] = str(choice) else: arg_choices = getattr(arg_state.action, ATTR_CHOICES_CALLABLE, None) if arg_choices is None: diff --git a/tests/test_argparse_completer.py b/tests/test_argparse_completer.py index 75f24b3e..6002a856 100644 --- a/tests/test_argparse_completer.py +++ b/tests/test_argparse_completer.py @@ -107,6 +107,7 @@ class ArgparseCompleterTester(cmd2.Cmd): int_choices = [-1, 1, -2, 2, 0, -12] static_choices_list = ['static', 'choices', 'stop', 'here'] choices_from_provider = ['choices', 'provider', 'probably', 'improved'] + completion_item_choices = [CompletionItem('choice_1', 'A description'), CompletionItem('choice_2', 'Another description')] def choices_provider(self) -> List[str]: """Method that provides choices""" @@ -150,6 +151,7 @@ class ArgparseCompleterTester(cmd2.Cmd): nargs=argparse.ONE_OR_MORE, ) choices_parser.add_argument('-i', '--int', type=int, help='a flag with an int type', choices=int_choices) + choices_parser.add_argument('--completion_items', help='choices are CompletionItems', choices=completion_item_choices) # Positional args for choices command choices_parser.add_argument("list_pos", help="a positional populated with a choices list", choices=static_choices_list) @@ -729,6 +731,23 @@ def test_completion_items(ac_app, num_aliases, show_description): assert 'help' in first_result_line +def test_completion_item_choices(ac_app): + text = '' + line = 'choices --completion_items {}'.format(text) + endidx = len(line) + begidx = endidx - len(text) + + first_match = complete_tester(text, line, begidx, endidx, ac_app) + assert first_match is not None + assert len(ac_app.completion_matches) == len(ac_app.completion_item_choices) + assert len(ac_app.display_matches) == len(ac_app.completion_item_choices) + + # Make sure a completion table was created + first_result_line = normalize(ac_app.formatted_completions)[1] + assert 'choice_1' in first_result_line + assert 'A description' in first_result_line + + @pytest.mark.parametrize( 'args, completions', [ |