Skip to content

Commit 70a8f3a

Browse files
committed
feat: Restore CompletionItem.description
Restores the `CompletionItem.description` field and expands its type to work with either `str` or `Sequence[str | rich.Column]`. This reverts a breaking change introduced in 3.0.0 and makes it easier for users to migrate from version 2.7.0.
1 parent 665ab52 commit 70a8f3a

File tree

4 files changed

+20
-16
lines changed

4 files changed

+20
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ time reading the [rich documentation](https://rich.readthedocs.io/).
3131
- `descriptive_header: str` replaced with `descriptive_headers: Sequence[str | rich.Column]`
3232
- Applies to parameter name when adding an argument to a parser as well as
3333
`set_descriptive_headers` and `get_descriptive_headers`
34-
- `CompletionItem.description: str` changed to
35-
`CompletionItem.descriptive_data: Sequence[str | rich.Column]`
34+
- Restored `CompletionItem.description` and expanded its type to work with either `str` or
35+
`Sequence[str | rich.Column]`
3636
- `decorators` module breaking changes:
3737
- `_set_parser_prog` renamed to `set_parser_prog` (without the leading underscore) and moved
3838
to `argparse_custom` module

cmd2/argparse_completer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ def _format_completions(self, arg_state: _ArgumentState, completions: list[str]
582582
border_style=Cmd2Style.TABLE_BORDER,
583583
)
584584
for item in completion_items:
585-
hint_table.add_row(item, *item.descriptive_data)
585+
hint_table.add_row(item, *item.description)
586586

587587
# Generate the hint table string
588588
console = Cmd2GeneralConsole()

cmd2/argparse_custom.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def my_completer(self, text, line, begidx, endidx, arg_tokens)
139139
that value's name. The right column header is defined using the
140140
``descriptive_headers`` parameter of add_argument(), which is a list of header
141141
names that defaults to ["Description"]. The right column values come from the
142-
``CompletionItem.descriptive_data`` member, which is a list with the same number
142+
``CompletionItem.description`` member, which is a list with the same number
143143
of items as columns defined in descriptive_headers.
144144
145145
To use CompletionItems, just return them from your choices_provider or
@@ -166,7 +166,7 @@ def my_completer(self, text, line, begidx, endidx, arg_tokens)
166166
def get_items(self) -> list[CompletionItems]:
167167
\"\"\"choices_provider which returns CompletionItems\"\"\"
168168
169-
# CompletionItem's second argument is descriptive_data.
169+
# CompletionItem's second argument is description.
170170
# Its item count should match that of descriptive_headers.
171171
return [
172172
CompletionItem(1, ["My item", True, "02/02/2022"]),
@@ -194,14 +194,14 @@ def get_items(self) -> list[CompletionItems]:
194194
truncated with an ellipsis at the end. You can override this and other settings
195195
when you create the ``Column``.
196196
197-
``descriptive_data`` items can include Rich objects, including styled Text and Tables.
197+
``description`` items can include Rich objects, including styled Text and Tables.
198198
199199
To avoid printing a excessive information to the screen at once when a user
200200
presses tab, there is a maximum threshold for the number of CompletionItems
201201
that will be shown. Its value is defined in ``cmd2.Cmd.max_completion_items``.
202202
It defaults to 50, but can be changed. If the number of completion suggestions
203203
exceeds this number, they will be displayed in the typical columnized format
204-
and will not include the descriptive_data of the CompletionItems.
204+
and will not include the description of the CompletionItems.
205205
206206
207207
**Patched argparse functions**
@@ -384,22 +384,26 @@ def __new__(cls, value: object, *_args: Any, **_kwargs: Any) -> 'CompletionItem'
384384
"""Responsible for creating and returning a new instance, called before __init__ when an object is instantiated."""
385385
return super().__new__(cls, value)
386386

387-
def __init__(self, value: object, descriptive_data: Sequence[Any], *args: Any) -> None:
387+
def __init__(self, value: object, description: str | Sequence[Any], *args: Any) -> None:
388388
"""CompletionItem Initializer.
389389
390390
:param value: the value being tab completed
391-
:param descriptive_data: a list of descriptive data to display in the columns that follow
392-
the completion value. The number of items in this list must equal
391+
:param description: a string or list of descriptive data to display in the columns that follow
392+
the completion value. If a list, the number of items in this list must equal
393393
the number of descriptive headers defined for the argument.
394394
:param args: args for str __init__
395395
"""
396396
super().__init__(*args)
397397

398+
# If description is a string, wrap it in a list
399+
if isinstance(description, str):
400+
description = [description]
401+
398402
# Make sure all objects are renderable by a Rich table.
399-
renderable_data = [obj if is_renderable(obj) else str(obj) for obj in descriptive_data]
403+
renderable_data = [obj if is_renderable(obj) else str(obj) for obj in description]
400404

401405
# Convert strings containing ANSI style sequences to Rich Text objects for correct display width.
402-
self.descriptive_data = ru.prepare_objects_for_rendering(*renderable_data)
406+
self.description = ru.prepare_objects_for_rendering(*renderable_data)
403407

404408
# Save the original value to support CompletionItems as argparse choices.
405409
# cmd2 has patched argparse so input is compared to this value instead of the CompletionItem instance.

tests/test_cmd2.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2306,7 +2306,7 @@ def test_get_alias_completion_items(base_app) -> None:
23062306
for cur_res in results:
23072307
assert cur_res in base_app.aliases
23082308
# Strip trailing spaces from table output
2309-
assert cur_res.descriptive_data[0].rstrip() == base_app.aliases[cur_res]
2309+
assert cur_res.description[0].rstrip() == base_app.aliases[cur_res]
23102310

23112311

23122312
def test_get_macro_completion_items(base_app) -> None:
@@ -2319,7 +2319,7 @@ def test_get_macro_completion_items(base_app) -> None:
23192319
for cur_res in results:
23202320
assert cur_res in base_app.macros
23212321
# Strip trailing spaces from table output
2322-
assert cur_res.descriptive_data[0].rstrip() == base_app.macros[cur_res].value
2322+
assert cur_res.description[0].rstrip() == base_app.macros[cur_res].value
23232323

23242324

23252325
def test_get_settable_completion_items(base_app) -> None:
@@ -2333,11 +2333,11 @@ def test_get_settable_completion_items(base_app) -> None:
23332333
# These CompletionItem descriptions are a two column table (Settable Value and Settable Description)
23342334
# First check if the description text starts with the value
23352335
str_value = str(cur_settable.value)
2336-
assert cur_res.descriptive_data[0].startswith(str_value)
2336+
assert cur_res.description[0].startswith(str_value)
23372337

23382338
# The second column is likely to have wrapped long text. So we will just examine the
23392339
# first couple characters to look for the Settable's description.
2340-
assert cur_settable.description[0:10] in cur_res.descriptive_data[1]
2340+
assert cur_settable.description[0:10] in cur_res.description[1]
23412341

23422342

23432343
def test_alias_no_subcommand(base_app) -> None:

0 commit comments

Comments
 (0)