From fdc96f8c0e224712e5b5fdb3fb0284d7fedb4570 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 17 Oct 2023 10:45:25 +0100 Subject: [PATCH] fix for cache (#3538) --- CHANGELOG.md | 6 ++++++ src/textual/_cache.py | 12 ++++++++++-- src/textual/widgets/_log.py | 1 + tests/test_cache.py | 26 ++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e78e774d64..0ce2439011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). + ## Unreleased +### Fixed + +- Fixed issue with LRUCache.discard https://github.com/Textualize/textual/issues/3537 + ### Changed - Buttons will now display multiple lines, and have auto height https://github.com/Textualize/textual/pull/3539 + ## [0.40.0] - 2023-10-11 - Added `loading` reactive property to widgets https://github.com/Textualize/textual/pull/3509 diff --git a/src/textual/_cache.py b/src/textual/_cache.py index a4b440e602..79a589ff0e 100644 --- a/src/textual/_cache.py +++ b/src/textual/_cache.py @@ -183,14 +183,22 @@ def discard(self, key: CacheKey) -> None: Args: key: Cache key. """ - link = self._cache.get(key) - if link is None: + if key not in self._cache: return + link = self._cache[key] + # Remove link from list link[0][1] = link[1] # type: ignore[index] link[1][0] = link[0] # type: ignore[index] # Remove link from cache + + if self._head[2] == key: + self._head = self._head[1] # type: ignore[assignment] + if self._head[2] == key: # type: ignore[index] + self._head = [] + del self._cache[key] + self._full = False class FIFOCache(Generic[CacheKey, CacheValue]): diff --git a/src/textual/widgets/_log.py b/src/textual/widgets/_log.py index b80f1c9dea..60e343c6a3 100644 --- a/src/textual/widgets/_log.py +++ b/src/textual/widgets/_log.py @@ -294,6 +294,7 @@ def _render_line_strip(self, y: int, rich_style: Style) -> Strip: line = Strip(line_text.render(self.app.console), cell_len(_line)) else: line = Strip([Segment(_line, rich_style)], cell_len(_line)) + self._render_line_cache[y] = line return line diff --git a/tests/test_cache.py b/tests/test_cache.py index ed2cb028f8..935c5dbfbe 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -259,3 +259,29 @@ def test_discard(): cache.discard("key4") # key that does not exist assert len(cache) == 2 # size should not change + + +def test_discard_regression(): + """Regression test for https://github.com/Textualize/textual/issues/3537""" + + cache = LRUCache(maxsize=3) + cache[1] = "foo" + cache[2] = "bar" + cache[3] = "baz" + cache[4] = "egg" + + assert cache.keys() == {2, 3, 4} + + cache.discard(2) + assert cache.keys() == {3, 4} + + cache[5] = "bob" + assert cache.keys() == {3, 4, 5} + + cache.discard(5) + assert cache.keys() == {3, 4} + + cache.discard(4) + cache.discard(3) + + assert cache.keys() == set()