diff --git a/CHANGELOG.md b/CHANGELOG.md index 556c442ea8..a4b991648b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,12 @@ 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 +## [0.80.1] - 2024-09-24 ### Fixed - Fixed crash when exiting the app prematurely https://github.com/Textualize/textual/pull/5039 +- Fixed exception constructing TextArea outside of App https://github.com/Textualize/textual/pull/5045 ## [0.80.0] - 2024-09-23 @@ -2387,6 +2388,7 @@ https://textual.textualize.io/blog/2022/11/08/version-040/#version-040 - New handler system for messages that doesn't require inheritance - Improved traceback handling +[0.80.1]: https://github.com/Textualize/textual/compare/v0.80.0...v0.80.1 [0.80.0]: https://github.com/Textualize/textual/compare/v0.79.0...v0.80.0 [0.79.0]: https://github.com/Textualize/textual/compare/v0.78.0...v0.79.0 [0.78.0]: https://github.com/Textualize/textual/compare/v0.77.0...v0.78.0 diff --git a/pyproject.toml b/pyproject.toml index feced1d81d..b96e9c75e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "textual" -version = "0.80.0" +version = "0.80.1" homepage = "https://github.com/Textualize/textual" repository = "https://github.com/Textualize/textual" documentation = "https://textual.textualize.io/" diff --git a/src/textual/widgets/_text_area.py b/src/textual/widgets/_text_area.py index 283623d4c1..970e5f5feb 100644 --- a/src/textual/widgets/_text_area.py +++ b/src/textual/widgets/_text_area.py @@ -464,9 +464,6 @@ def __init__( self.tab_behavior = tab_behavior - # When `app.dark` is toggled, reset the theme (since it caches values). - self.watch(self.app, "dark", self._app_dark_toggled, init=False) - if tooltip is not None: self.tooltip = tooltip @@ -610,6 +607,10 @@ def _watch_selection( ) -> None: """When the cursor moves, scroll it into view.""" # Find the visual offset of the cursor in the document + + if not self.is_mounted: + return + cursor_location = selection.end self.scroll_cursor_visible() @@ -1519,6 +1520,9 @@ def gutter_width(self) -> int: return gutter_width def _on_mount(self, event: events.Mount) -> None: + # When `app.dark` is toggled, reset the theme (since it caches values). + self.watch(self.app, "dark", self._app_dark_toggled, init=False) + self.blink_timer = self.set_interval( 0.5, self._toggle_cursor_blink_visible, diff --git a/tests/test_widget.py b/tests/test_widget.py index 6643916bbb..146e4fbe96 100644 --- a/tests/test_widget.py +++ b/tests/test_widget.py @@ -12,7 +12,46 @@ from textual.geometry import Offset, Size from textual.message import Message from textual.widget import BadWidgetName, MountError, PseudoClasses, Widget -from textual.widgets import Label, LoadingIndicator +from textual.widgets import ( + Button, + DataTable, + Footer, + Header, + Input, + Label, + LoadingIndicator, + Log, + OptionList, + RichLog, + Switch, + TextArea, +) + + +async def test_widget_construct(): + """Regression test for https://github.com/Textualize/textual/issues/5042""" + + # Check that constructing the widget outside of the app, doesn't invoke code that + # expects an active app. + class MyApp(App): + def __init__(self) -> None: + super().__init__() + self.button = Button() + self.data_table = DataTable() + self.footer = Footer() + self.header = Header() + self.input = Input() + self.label = Label() + self.loading_indicator = LoadingIndicator() + self.log_ = Log() + self.option_list = OptionList() + self.rich_log = RichLog() + self.switch = Switch() + self.text_area = TextArea(language="python") + + app = MyApp() + async with app.run_test(): + pass @pytest.mark.parametrize(