Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicitly type attribute sender in messages. #1922

Closed
wants to merge 11 commits into from
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- Widget scrolling methods (such as `Widget.scroll_home` and `Widget.scroll_end`) now perform the scroll after the next refresh https://github.com/Textualize/textual/issues/1774
- Buttons no longer accept arbitrary renderables https://github.com/Textualize/textual/issues/1870
- `DataTable`-related events are now generics over the type of the `DataTable` that posts those events (see `Tree` for another example) https://github.com/Textualize/textual/issues/1813

### Fixed
### Removed

- Scrolling with cursor keys now moves just one cell https://github.com/Textualize/textual/issues/1897
- Removed the attribute `Button.Pressed.button` in favour of `Button.Pressed.sender` https://github.com/Textualize/textual/issues/1813
- Removed the attributes `Input.Changed.input` and `Input.Submitted.input` in favour of the respective `Input.Changed.sender` and `Input.Submitted.sender` attributes https://github.com/Textualize/textual/issues/1813
- Removed the attribute `RadioSet.Changed.input` in favour of `RadioSet.Changed.sender` https://github.com/Textualize/textual/issues/1813
- Removed the attribute `Switch.Changed.input` in favour of `Switch.Changed.sender` https://github.com/Textualize/textual/issues/1813
- Removed the attribute `ToggleButton.Changed.input` in favour of `ToggleButton.Changed.sender` https://github.com/Textualize/textual/issues/1813

### Fixed

- Scrolling with cursor keys now moves just one cell https://github.com/Textualize/textual/issues/1897
- Fix exceptions in watch methods being hidden on startup https://github.com/Textualize/textual/issues/1886

## [0.12.1] - 2023-02-25
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/app/question01.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from textual.app import App, ComposeResult
from textual.widgets import Label, Button
from textual.widgets import Button, Label


class QuestionApp(App[str]):
Expand All @@ -9,7 +9,7 @@ def compose(self) -> ComposeResult:
yield Button("No", id="no", variant="error")

def on_button_pressed(self, event: Button.Pressed) -> None:
self.exit(event.button.id)
self.exit(event.sender.id)


if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/app/question02.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from textual.app import App, ComposeResult
from textual.widgets import Label, Button
from textual.widgets import Button, Label


class QuestionApp(App[str]):
Expand All @@ -11,7 +11,7 @@ def compose(self) -> ComposeResult:
yield Button("No", id="no", variant="error")

def on_button_pressed(self, event: Button.Pressed) -> None:
self.exit(event.button.id)
self.exit(event.sender.id)


if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/app/question03.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from textual.app import App, ComposeResult
from textual.widgets import Label, Button
from textual.widgets import Button, Label


class QuestionApp(App[str]):
Expand Down Expand Up @@ -29,7 +29,7 @@ def compose(self) -> ComposeResult:
yield Button("No", id="no", variant="error")

def on_button_pressed(self, event: Button.Pressed) -> None:
self.exit(event.button.id)
self.exit(event.sender.id)


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/app/question_title01.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def compose(self) -> ComposeResult:
yield Button("No", id="no", variant="error")

def on_button_pressed(self, event: Button.Pressed) -> None:
self.exit(event.button.id)
self.exit(event.sender.id)


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/app/question_title02.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def compose(self) -> ComposeResult:
yield Button("No", id="no", variant="error")

def on_button_pressed(self, event: Button.Pressed) -> None:
self.exit(event.button.id)
self.exit(event.sender.id)

def on_key(self, event: Key):
self.title = event.key
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/guide/reactivity/computed01.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ def on_input_changed(self, event: Input.Changed) -> None:
except ValueError:
self.bell()
else:
if event.input.id == "red":
if event.sender.id == "red":
self.red = component
elif event.input.id == "green":
elif event.sender.id == "green":
self.green = component
else:
self.blue = component
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/guide/reactivity/validate01.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def compose(self) -> ComposeResult:
yield TextLog(highlight=True)

def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == "plus":
if event.sender.id == "plus":
self.count += 1
else:
self.count -= 1
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/guide/screens/modal01.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from textual.app import App, ComposeResult
from textual.containers import Grid
from textual.screen import Screen
from textual.widgets import Static, Header, Footer, Button
from textual.widgets import Button, Footer, Header, Static


class QuitScreen(Screen):
Expand All @@ -14,7 +14,7 @@ def compose(self) -> ComposeResult:
)

def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == "quit":
if event.sender.id == "quit":
self.app.exit()
else:
self.app.pop_screen()
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/tutorial/stopwatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from textual.app import App, ComposeResult
from textual.containers import Container
from textual.reactive import reactive
from textual.widgets import Button, Header, Footer, Static
from textual.widgets import Button, Footer, Header, Static


class TimeDisplay(Static):
Expand Down Expand Up @@ -49,7 +49,7 @@ class Stopwatch(Static):

def on_button_pressed(self, event: Button.Pressed) -> None:
"""Event handler called when a button is pressed."""
button_id = event.button.id
button_id = event.sender.id
time_display = self.query_one(TimeDisplay)
if button_id == "start":
time_display.start()
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/tutorial/stopwatch04.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from textual.app import App, ComposeResult
from textual.containers import Container
from textual.widgets import Button, Header, Footer, Static
from textual.widgets import Button, Footer, Header, Static


class TimeDisplay(Static):
Expand All @@ -12,9 +12,9 @@ class Stopwatch(Static):

def on_button_pressed(self, event: Button.Pressed) -> None:
"""Event handler called when a button is pressed."""
if event.button.id == "start":
if event.sender.id == "start":
self.add_class("started")
elif event.button.id == "stop":
elif event.sender.id == "stop":
self.remove_class("started")

def compose(self) -> ComposeResult:
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/tutorial/stopwatch05.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from textual.app import App, ComposeResult
from textual.containers import Container
from textual.reactive import reactive
from textual.widgets import Button, Header, Footer, Static
from textual.widgets import Button, Footer, Header, Static


class TimeDisplay(Static):
Expand Down Expand Up @@ -32,9 +32,9 @@ class Stopwatch(Static):

def on_button_pressed(self, event: Button.Pressed) -> None:
"""Event handler called when a button is pressed."""
if event.button.id == "start":
if event.sender.id == "start":
self.add_class("started")
elif event.button.id == "stop":
elif event.sender.id == "stop":
self.remove_class("started")

def compose(self) -> ComposeResult:
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/tutorial/stopwatch06.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from textual.app import App, ComposeResult
from textual.containers import Container
from textual.reactive import reactive
from textual.widgets import Button, Header, Footer, Static
from textual.widgets import Button, Footer, Header, Static


class TimeDisplay(Static):
Expand Down Expand Up @@ -49,7 +49,7 @@ class Stopwatch(Static):

def on_button_pressed(self, event: Button.Pressed) -> None:
"""Event handler called when a button is pressed."""
button_id = event.button.id
button_id = event.sender.id
time_display = self.query_one(TimeDisplay)
if button_id == "start":
time_display.start()
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/widgets/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def compose(self) -> ComposeResult:
)

def on_button_pressed(self, event: Button.Pressed) -> None:
self.exit(str(event.button))
self.exit(str(event.sender))


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion examples/calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def press(button_id: str) -> None:
def on_button_pressed(self, event: Button.Pressed) -> None:
"""Called when a button is pressed."""

button_id = event.button.id
button_id = event.sender.id
assert button_id is not None

def do_math() -> None:
Expand Down
2 changes: 1 addition & 1 deletion examples/five_by_five.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def on_button_pressed(self, event: GameCell.Pressed) -> None:
Args:
event (GameCell.Pressed): The event to react to.
"""
self.make_move_on(cast(GameCell, event.button))
self.make_move_on(cast(GameCell, event.sender))

def action_new_game(self) -> None:
"""Start a new game."""
Expand Down
2 changes: 1 addition & 1 deletion src/textual/cli/previews/borders.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def compose(self):

def on_button_pressed(self, event: Button.Pressed) -> None:
self.text.styles.border = (
event.button.id,
event.sender.id,
self.stylesheet._variables["secondary"],
)
self.bell()
Expand Down
2 changes: 1 addition & 1 deletion src/textual/cli/previews/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def update_view(self) -> None:

def on_button_pressed(self, event: Button.Pressed) -> None:
self.query(ColorGroup).remove_class("-active")
group = self.query_one(f"#group-{event.button.id}", ColorGroup)
group = self.query_one(f"#group-{event.sender.id}", ColorGroup)
group.add_class("-active")
group.scroll_visible(top=True, speed=150)

Expand Down
6 changes: 3 additions & 3 deletions src/textual/cli/previews/easing.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,13 @@ def _animation_complete():
target_position = (
END_POSITION if self.position == START_POSITION else START_POSITION
)
assert event.button.id is not None # Should be set to an easing function str.
assert event.sender.id is not None # Should be set to an easing function str.
self.animate(
"position",
value=target_position,
final_value=target_position,
duration=self.duration,
easing=event.button.id,
easing=event.sender.id,
on_complete=_animation_complete,
)

Expand All @@ -107,7 +107,7 @@ def watch_position(self, value: int):
self.opacity_widget.styles.opacity = 1 - value / END_POSITION

def on_input_changed(self, event: Input.Changed):
if event.input.id == "duration-input":
if event.sender.id == "duration-input":
new_duration = _try_float(event.value)
if new_duration is not None:
self.duration = new_duration
Expand Down
4 changes: 2 additions & 2 deletions src/textual/cli/previews/keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ def on_key(self, event: events.Key) -> None:
self.last_key = event.key

def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == "quit":
if event.sender.id == "quit":
self.exit()
elif event.button.id == "clear":
elif event.sender.id == "clear":
self.query_one(KeyLog).clear()


Expand Down
8 changes: 5 additions & 3 deletions src/textual/scrollbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from rich.style import Style, StyleType

from . import events
from ._types import MessageTarget
from .geometry import Offset
from .message import Message
from .reactive import Reactive
Expand All @@ -19,7 +18,10 @@


class ScrollMessage(Message, bubble=False):
pass
"""Base class for all messages posted by the scrollbar."""

sender: ScrollBar
"""The scrollbar that posted the message."""


@rich.repr.auto
Expand Down Expand Up @@ -47,7 +49,7 @@ class ScrollTo(ScrollMessage, verbose=True):

def __init__(
self,
sender: MessageTarget,
sender: ScrollBar,
x: float | None = None,
y: float | None = None,
animate: bool = True,
Expand Down
8 changes: 2 additions & 6 deletions src/textual/widgets/_button.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,10 @@ class Pressed(Message, bubble=True):

Can be handled using `on_button_pressed` in a subclass of `Button` or
in a parent widget in the DOM.

Attributes:
button: The button that was pressed.
"""

@property
def button(self) -> Button:
return cast(Button, self.sender)
sender: Button
"""The button that posted the message."""

def __init__(
self,
Expand Down
Loading