From 95453fbcd72edc0ee07896e2154aca2038407731 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 6 Mar 2024 10:24:46 +0000 Subject: [PATCH 1/6] Clean out trailing whitespace --- src/textual/widgets/_button.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/textual/widgets/_button.py b/src/textual/widgets/_button.py index 83a3237b2d..29daf153bc 100644 --- a/src/textual/widgets/_button.py +++ b/src/textual/widgets/_button.py @@ -61,16 +61,16 @@ class Button(Widget, can_focus=True): tint: $background 30%; } - &.-primary { + &.-primary { background: $primary; color: $text; border-top: tall $primary-lighten-3; - border-bottom: tall $primary-darken-3; - + border-bottom: tall $primary-darken-3; + &:hover { background: $primary-darken-2; color: $text; - border-top: tall $primary; + border-top: tall $primary; } &.-active { From 3ce49778087e7c43a28ab478be9adcef6919853b Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 6 Mar 2024 11:44:20 +0000 Subject: [PATCH 2/6] Clean up the return type for widget render methods Use the type hint that is talked about in the documentation. Fixes #4063. --- src/textual/widgets/_button.py | 8 ++++++-- src/textual/widgets/_digits.py | 7 ++++--- src/textual/widgets/_footer.py | 9 ++++++--- src/textual/widgets/_input.py | 13 +++++++++---- src/textual/widgets/_loading_indicator.py | 6 ++++-- src/textual/widgets/_placeholder.py | 7 +++++-- src/textual/widgets/_static.py | 7 ++++++- src/textual/widgets/_switch.py | 6 +++--- src/textual/widgets/_toast.py | 9 ++++++--- 9 files changed, 49 insertions(+), 23 deletions(-) diff --git a/src/textual/widgets/_button.py b/src/textual/widgets/_button.py index 29daf153bc..110646e109 100644 --- a/src/textual/widgets/_button.py +++ b/src/textual/widgets/_button.py @@ -1,7 +1,7 @@ from __future__ import annotations from functools import partial -from typing import cast +from typing import TYPE_CHECKING, cast import rich.repr from rich.console import ConsoleRenderable, RenderableType @@ -9,6 +9,10 @@ from typing_extensions import Literal, Self from .. import events + +if TYPE_CHECKING: + from ..app import RenderResult + from ..binding import Binding from ..css._error_tools import friendly_list from ..message import Message @@ -220,7 +224,7 @@ def validate_label(self, label: TextType) -> Text: return Text.from_markup(label) return label - def render(self) -> RenderableType: + def render(self) -> RenderResult: assert isinstance(self.label, Text) label = self.label.copy() label.stylize(self.rich_style) diff --git a/src/textual/widgets/_digits.py b/src/textual/widgets/_digits.py index d298f4e3e9..3bd04fcc25 100644 --- a/src/textual/widgets/_digits.py +++ b/src/textual/widgets/_digits.py @@ -1,10 +1,11 @@ from __future__ import annotations -from typing import cast +from typing import TYPE_CHECKING, cast from rich.align import Align, AlignMethod -from rich.console import RenderableType +if TYPE_CHECKING: + from ..app import RenderResult from ..geometry import Size from ..renderables.digits import Digits as DigitsRenderable from ..widget import Widget @@ -68,7 +69,7 @@ def update(self, value: str) -> None: self._value = value self.refresh(layout=layout_required) - def render(self) -> RenderableType: + def render(self) -> RenderResult: """Render digits.""" rich_style = self.rich_style digits = DigitsRenderable(self._value, rich_style) diff --git a/src/textual/widgets/_footer.py b/src/textual/widgets/_footer.py index b5e772ab60..5f3c60d925 100644 --- a/src/textual/widgets/_footer.py +++ b/src/textual/widgets/_footer.py @@ -1,13 +1,16 @@ from __future__ import annotations from collections import defaultdict -from typing import ClassVar, Optional +from typing import TYPE_CHECKING, ClassVar, Optional import rich.repr -from rich.console import RenderableType from rich.text import Text from .. import events + +if TYPE_CHECKING: + from ..app import RenderResult + from ..reactive import reactive from ..widget import Widget @@ -138,7 +141,7 @@ def notify_style_update(self) -> None: def post_render(self, renderable): return renderable - def render(self) -> RenderableType: + def render(self) -> RenderResult: if self._key_text is None: self._key_text = self._make_key_text() return self._key_text diff --git a/src/textual/widgets/_input.py b/src/textual/widgets/_input.py index 828f2ff4ac..b9d217142c 100644 --- a/src/textual/widgets/_input.py +++ b/src/textual/widgets/_input.py @@ -2,10 +2,11 @@ import re from dataclasses import dataclass -from typing import ClassVar, Iterable +from typing import TYPE_CHECKING, ClassVar, Iterable from rich.cells import cell_len, get_character_cell_size -from rich.console import Console, ConsoleOptions, RenderableType, RenderResult +from rich.console import Console, ConsoleOptions +from rich.console import RenderResult as RichRenderResult from rich.highlighter import Highlighter from rich.segment import Segment from rich.text import Text @@ -13,6 +14,10 @@ from .. import events from .._segment_tools import line_crop + +if TYPE_CHECKING: + from ..app import RenderResult + from ..binding import Binding, BindingType from ..css._error_tools import friendly_list from ..events import Blur, Focus, Mount @@ -47,7 +52,7 @@ def __init__(self, input: Input, cursor_visible: bool) -> None: def __rich_console__( self, console: "Console", options: "ConsoleOptions" - ) -> "RenderResult": + ) -> "RichRenderResult": input = self.input result = input._value width = input.content_size.width @@ -460,7 +465,7 @@ def cursor_width(self) -> int: return cell_len(self.placeholder) return self._position_to_cell(len(self.value)) + 1 - def render(self) -> RenderableType: + def render(self) -> RenderResult: self.view_position = self.view_position if not self.value: placeholder = Text(self.placeholder, justify="left") diff --git a/src/textual/widgets/_loading_indicator.py b/src/textual/widgets/_loading_indicator.py index 24bc3cf2de..c715bbb997 100644 --- a/src/textual/widgets/_loading_indicator.py +++ b/src/textual/widgets/_loading_indicator.py @@ -1,11 +1,13 @@ from __future__ import annotations from time import time +from typing import TYPE_CHECKING -from rich.console import RenderableType from rich.style import Style from rich.text import Text +if TYPE_CHECKING: + from ..app import RenderResult from ..color import Gradient from ..events import Mount from ..widget import Widget @@ -53,7 +55,7 @@ def _on_mount(self, _: Mount) -> None: self._start_time = time() self.auto_refresh = 1 / 16 - def render(self) -> RenderableType: + def render(self) -> RenderResult: if self.app.animation_level == "none": return Text("Loading...") diff --git a/src/textual/widgets/_placeholder.py b/src/textual/widgets/_placeholder.py index 9c9adf725c..bc905001bc 100644 --- a/src/textual/widgets/_placeholder.py +++ b/src/textual/widgets/_placeholder.py @@ -6,10 +6,13 @@ from typing import TYPE_CHECKING, Iterator from weakref import WeakKeyDictionary -from rich.console import RenderableType from typing_extensions import Literal, Self from .. import events + +if TYPE_CHECKING: + from ..app import RenderResult + from ..css._error_tools import friendly_list from ..reactive import Reactive, reactive from ..widget import Widget @@ -128,7 +131,7 @@ async def _on_compose(self, event: events.Compose) -> None: ) self.styles.background = f"{next(colors)} 50%" - def render(self) -> RenderableType: + def render(self) -> RenderResult: """Render the placeholder. Returns: diff --git a/src/textual/widgets/_static.py b/src/textual/widgets/_static.py index 3ccd43c3df..81215fd30d 100644 --- a/src/textual/widgets/_static.py +++ b/src/textual/widgets/_static.py @@ -1,9 +1,14 @@ from __future__ import annotations +from typing import TYPE_CHECKING + from rich.console import RenderableType from rich.protocol import is_renderable from rich.text import Text +if TYPE_CHECKING: + from ..app import RenderResult + from ..errors import RenderError from ..widget import Widget @@ -80,7 +85,7 @@ def renderable(self, renderable: RenderableType) -> None: self._renderable = renderable self.clear_cached_dimensions() - def render(self) -> RenderableType: + def render(self) -> RenderResult: """Get a rich renderable for the widget's content. Returns: diff --git a/src/textual/widgets/_switch.py b/src/textual/widgets/_switch.py index 96cce3eeb8..3060163bfe 100644 --- a/src/textual/widgets/_switch.py +++ b/src/textual/widgets/_switch.py @@ -2,8 +2,8 @@ from typing import TYPE_CHECKING, ClassVar -from rich.console import RenderableType - +if TYPE_CHECKING: + from ..app import RenderResult from ..binding import Binding, BindingType from ..events import Click from ..geometry import Size @@ -143,7 +143,7 @@ def watch_value(self, value: bool) -> None: def watch_slider_pos(self, slider_pos: float) -> None: self.set_class(slider_pos == 1, "-on") - def render(self) -> RenderableType: + def render(self) -> RenderResult: style = self.get_component_rich_style("switch--slider") return ScrollBarRender( virtual_size=100, diff --git a/src/textual/widgets/_toast.py b/src/textual/widgets/_toast.py index e55eaa0135..a8198f4b53 100644 --- a/src/textual/widgets/_toast.py +++ b/src/textual/widgets/_toast.py @@ -2,12 +2,15 @@ from __future__ import annotations -from typing import ClassVar +from typing import TYPE_CHECKING, ClassVar -from rich.console import RenderableType from rich.text import Text from .. import on + +if TYPE_CHECKING: + from ..app import RenderResult + from ..containers import Container from ..css.query import NoMatches from ..events import Click, Mount @@ -105,7 +108,7 @@ def __init__(self, notification: Notification) -> None: self._notification = notification self._timeout = notification.time_left - def render(self) -> RenderableType: + def render(self) -> RenderResult: """Render the toast's content. Returns: From 006328fff27bcba138e4f0bd1d7a9b259ff48dae Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 6 Mar 2024 14:11:48 +0000 Subject: [PATCH 3/6] Correct the type hint for App.render --- src/textual/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/app.py b/src/textual/app.py index 124f2d25c2..01b3634a99 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -1593,7 +1593,7 @@ async def _on_css_change(self) -> None: for screen in self.screen_stack: self.stylesheet.update(screen) - def render(self) -> RenderableType: + def render(self) -> RenderResult: return Blank(self.styles.background) ExpectType = TypeVar("ExpectType", bound=Widget) From 535917e3b46370a400a9eeb584002b256597c700 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 6 Mar 2024 14:13:38 +0000 Subject: [PATCH 4/6] Correct the render return type hint in the docs example --- docs/examples/how-to/render_compose.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples/how-to/render_compose.py b/docs/examples/how-to/render_compose.py index b1413d3d0c..06ce6a7fa8 100644 --- a/docs/examples/how-to/render_compose.py +++ b/docs/examples/how-to/render_compose.py @@ -1,6 +1,6 @@ from time import time -from textual.app import App, ComposeResult, RenderableType +from textual.app import App, ComposeResult, RenderResult from textual.containers import Container from textual.renderables.gradient import LinearGradient from textual.widgets import Static @@ -41,7 +41,7 @@ def on_mount(self) -> None: def compose(self) -> ComposeResult: yield Static("Making a splash with Textual!") # (2)! - def render(self) -> RenderableType: + def render(self) -> RenderResult: return LinearGradient(time() * 90, STOPS) # (3)! From 3326ee41eb1bbcfd851f4c4e0305c137db0c85ed Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 6 Mar 2024 14:29:47 +0000 Subject: [PATCH 5/6] Correct the Widget.render return type hint --- src/textual/widget.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/textual/widget.py b/src/textual/widget.py index cd140df807..17a7723755 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -32,15 +32,18 @@ ConsoleRenderable, JustifyMethod, RenderableType, - RenderResult, - RichCast, ) +from rich.console import RenderResult as RichRenderResult +from rich.console import RichCast from rich.measure import Measurement from rich.segment import Segment from rich.style import Style from rich.text import Text from typing_extensions import Self +if TYPE_CHECKING: + from .app import RenderResult + from . import constants, errors, events, messages from ._animator import DEFAULT_EASING, Animatable, BoundAnimator, EasingFunction from ._arrange import DockArrangeResult, arrange @@ -152,7 +155,7 @@ def __init__( def __rich_console__( self, console: "Console", options: "ConsoleOptions" - ) -> "RenderResult": + ) -> "RichRenderResult": style = console.get_style(self.style) result_segments = console.render(self.renderable, options) @@ -3375,7 +3378,7 @@ async def batch(self) -> AsyncGenerator[None, None]: with self.app.batch_update(): yield - def render(self) -> RenderableType: + def render(self) -> RenderResult: """Get text or Rich renderable for this widget. Implement this for custom widgets. From 32347897eff3c639083330ebecf74f9c5ef113a0 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Wed, 6 Mar 2024 15:56:17 +0000 Subject: [PATCH 6/6] Unquote a type hint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Rodrigo Girão Serrão <5621605+rodrigogiraoserrao@users.noreply.github.com> --- src/textual/widgets/_input.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/widgets/_input.py b/src/textual/widgets/_input.py index b9d217142c..0d3149f2d3 100644 --- a/src/textual/widgets/_input.py +++ b/src/textual/widgets/_input.py @@ -52,7 +52,7 @@ def __init__(self, input: Input, cursor_visible: bool) -> None: def __rich_console__( self, console: "Console", options: "ConsoleOptions" - ) -> "RichRenderResult": + ) -> RichRenderResult: input = self.input result = input._value width = input.content_size.width