Skip to content

Commit 462e162

Browse files
authored
Merge pull request #1069 from python-cmd2/completion_item_choices
Fixed issue where argparse choices could not be CompletionItems
2 parents cc9d96a + 5732bc3 commit 462e162

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

cmd2/argparse_completer.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -641,8 +641,11 @@ def _complete_arg(
641641
arg_choices.sort()
642642
self._cmd2_app.matches_sorted = True
643643

644-
# Since choices can be various types, convert them all to strings
645-
arg_choices = [str(x) for x in arg_choices]
644+
# Since choices can be various types, make sure they are all strings
645+
for index, choice in enumerate(arg_choices):
646+
# Prevent converting anything that is already a str (i.e. CompletionItem)
647+
if not isinstance(choice, str):
648+
arg_choices[index] = str(choice)
646649
else:
647650
arg_choices = getattr(arg_state.action, ATTR_CHOICES_CALLABLE, None)
648651
if arg_choices is None:

tests/test_argparse_completer.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ def do_plus_flag(self, args: argparse.Namespace) -> None:
107107
int_choices = [-1, 1, -2, 2, 0, -12]
108108
static_choices_list = ['static', 'choices', 'stop', 'here']
109109
choices_from_provider = ['choices', 'provider', 'probably', 'improved']
110+
completion_item_choices = [CompletionItem('choice_1', 'A description'), CompletionItem('choice_2', 'Another description')]
110111

111112
def choices_provider(self) -> List[str]:
112113
"""Method that provides choices"""
@@ -150,6 +151,7 @@ def completion_item_method(self) -> List[CompletionItem]:
150151
nargs=argparse.ONE_OR_MORE,
151152
)
152153
choices_parser.add_argument('-i', '--int', type=int, help='a flag with an int type', choices=int_choices)
154+
choices_parser.add_argument('--completion_items', help='choices are CompletionItems', choices=completion_item_choices)
153155

154156
# Positional args for choices command
155157
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):
729731
assert 'help' in first_result_line
730732

731733

734+
def test_completion_item_choices(ac_app):
735+
text = ''
736+
line = 'choices --completion_items {}'.format(text)
737+
endidx = len(line)
738+
begidx = endidx - len(text)
739+
740+
first_match = complete_tester(text, line, begidx, endidx, ac_app)
741+
assert first_match is not None
742+
assert len(ac_app.completion_matches) == len(ac_app.completion_item_choices)
743+
assert len(ac_app.display_matches) == len(ac_app.completion_item_choices)
744+
745+
# Make sure a completion table was created
746+
first_result_line = normalize(ac_app.formatted_completions)[1]
747+
assert 'choice_1' in first_result_line
748+
assert 'A description' in first_result_line
749+
750+
732751
@pytest.mark.parametrize(
733752
'args, completions',
734753
[

0 commit comments

Comments
 (0)