From 17e975db679bbe15877a57ac7a9390260a6ee386 Mon Sep 17 00:00:00 2001 From: TomJGooding <101601846+TomJGooding@users.noreply.github.com> Date: Thu, 2 May 2024 17:07:32 +0100 Subject: [PATCH] fix(selection list): update indexes after option removed (#4464) * fix(selection list): update indexes after option removed * add basic test * update changelog * improve test --------- Co-authored-by: Darren Burns --- CHANGELOG.md | 4 +--- src/textual/widgets/_selection_list.py | 5 +++++ tests/selection_list/test_selection_list_create.py | 9 +++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88847d849e..575e3ee22e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,15 +9,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +- Fixed `SelectionList` issues after removing an option https://github.com/Textualize/textual/pull/4464 - Fixed `ListView` bugs with the initial index https://github.com/Textualize/textual/pull/4452 -## Unreleased - ### Changed - When displaying a message using `App.exit()`, the console no longer highlights things such as numbers. - ## [0.58.1] - 2024-05-01 ### Fixed diff --git a/src/textual/widgets/_selection_list.py b/src/textual/widgets/_selection_list.py index 85f95b1326..3f9f961f22 100644 --- a/src/textual/widgets/_selection_list.py +++ b/src/textual/widgets/_selection_list.py @@ -646,6 +646,11 @@ def _remove_option(self, index: int) -> None: option = self.get_option_at_index(index) self._deselect(option.value) del self._values[option.value] + # Decrement index of options after the one we just removed. + self._values = { + option_value: option_index - 1 if option_index > index else option_index + for option_value, option_index in self._values.items() + } return super()._remove_option(index) def add_options( diff --git a/tests/selection_list/test_selection_list_create.py b/tests/selection_list/test_selection_list_create.py index e189a3c9d5..114bb69bd3 100644 --- a/tests/selection_list/test_selection_list_create.py +++ b/tests/selection_list/test_selection_list_create.py @@ -114,3 +114,12 @@ async def test_options_are_available_soon() -> None: selection = Selection("", 0, id="some_id") selection_list = SelectionList[int](selection) assert selection_list.get_option("some_id") is selection + + +async def test_removing_option_updates_indexes() -> None: + async with SelectionListApp().run_test() as pilot: + selections = pilot.app.query_one(SelectionList) + assert selections._values == {n: n for n in range(5)} + + selections.remove_option_at_index(0) + assert selections._values == {n + 1: n for n in range(4)}