From 57fa794275e39dcb53de054ec506ff9b9d41316d Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 6 Jul 2023 13:58:07 +0100 Subject: [PATCH 1/3] Rodrigo's test --- src/textual/timer.py | 2 ++ tests/test_await_remove.py | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/test_await_remove.py diff --git a/src/textual/timer.py b/src/textual/timer.py index 42e6b97897..db4041b6dd 100644 --- a/src/textual/timer.py +++ b/src/textual/timer.py @@ -148,6 +148,8 @@ async def _tick(self, *, next_timer: float, count: int) -> None: if self._callback is not None: try: await invoke(self._callback) + except CancelledError: + raise except Exception as error: app = active_app.get() app._handle_exception(error) diff --git a/tests/test_await_remove.py b/tests/test_await_remove.py new file mode 100644 index 0000000000..c6630afab3 --- /dev/null +++ b/tests/test_await_remove.py @@ -0,0 +1,22 @@ +from textual.app import App +from textual.widgets import Label + + +class SelfRemovingLabel(Label): + def on_mount(self) -> None: + self.set_timer(0.2, self.remove) + + +class RemoveOnTimerApp(App[None]): + def on_mount(self): + for _ in range(5): + self.mount(SelfRemovingLabel("I will remove myself!")) + + +async def test_multiple_simultaneous_removals(): + """Regression test for https://github.com/Textualize/textual/issues/2854.""" + # The app should run and finish without raising any errors. + async with RemoveOnTimerApp().run_test() as pilot: + await pilot.pause(0.3) + # Sanity check to ensure labels were removed. + assert len(pilot.app.query(Label)) == 0 From d23c86ff194312770c3fd6a977e51535424e1ebe Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 6 Jul 2023 14:01:45 +0100 Subject: [PATCH 2/3] changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3774e75a1..69553b024a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ 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 CancelledError issue with timer https://github.com/Textualize/textual/issues/2854 + + ## [0.29.0] - 2023-07-03 ### Changed @@ -23,6 +30,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fixed crash when columns were added to populated `DataTable` https://github.com/Textualize/textual/pull/2836 - Fixed issues with opacity on Screens https://github.com/Textualize/textual/issues/2616 - Fixed style problem with selected selections in a non-focused selection list https://github.com/Textualize/textual/issues/2768 +- Fixed sys.stdout and sys.stderr being None https://github.com/Textualize/textual/issues/2879 ## [0.28.1] - 2023-06-20 From beb33d589e770686c78c0bca43098d73f8d35123 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 6 Jul 2023 14:04:50 +0100 Subject: [PATCH 3/3] comment oddity --- src/textual/timer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/textual/timer.py b/src/textual/timer.py index db4041b6dd..f708512de4 100644 --- a/src/textual/timer.py +++ b/src/textual/timer.py @@ -149,6 +149,8 @@ async def _tick(self, *, next_timer: float, count: int) -> None: try: await invoke(self._callback) except CancelledError: + # https://github.com/Textualize/textual/pull/2895 + # Re-raise CancelledErrors that would be caught by the following exception block in Python 3.7 raise except Exception as error: app = active_app.get()