From 0324fb90d1fd1e26cd34e18fa193acdb0e6460c3 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Tue, 8 Nov 2022 13:53:22 +0000 Subject: [PATCH] Hoist WidgetError and MountError to the top level of widget.py --- src/textual/widget.py | 24 +++++++++++++----------- tests/test_widget_mount_point.py | 4 ++-- tests/test_widget_mounting.py | 10 +++++----- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/textual/widget.py b/src/textual/widget.py index 5090995cc..b4723487c 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -147,6 +147,14 @@ class RenderCache(NamedTuple): lines: Lines +class WidgetError(Exception): + """Base widget error.""" + + +class MountError(WidgetError): + """Error raised when there was a problem with the mount request.""" + + @rich.repr.auto class Widget(DOMNode): """ @@ -189,9 +197,6 @@ class Widget(DOMNode): hover_style: Reactive[Style] = Reactive(Style, repaint=False) highlight_link_id: Reactive[str] = Reactive("") - class WidgetError(Exception): - """Base widget error.""" - def __init__( self, *children: Widget, @@ -238,7 +243,7 @@ class Widget(DOMNode): ) if self in children: - raise self.WidgetError("A widget can't be its own parent") + raise WidgetError("A widget can't be its own parent") self._add_children(*children) @@ -381,9 +386,6 @@ class Widget(DOMNode): if self._scrollbar_corner is not None: yield self._scrollbar_corner - class MountError(WidgetError): - """Error raised when there was a problem with the mount request.""" - def _find_mount_point(self, spot: int | str | "Widget") -> tuple["Widget", int]: """Attempt to locate the point where the caller wants to mount something. @@ -394,7 +396,7 @@ class Widget(DOMNode): tuple[Widget, int]: The parent and the location in its child list. Raises: - Widget.MountError: If there was an error finding where to mount a widget. + MountError: If there was an error finding where to mount a widget. The rules of this method are: @@ -421,7 +423,7 @@ class Widget(DOMNode): # have a parent? There's no way we can use it as a sibling to make # mounting decisions if it doesn't have a parent. if spot.parent is None: - raise self.MountError( + raise MountError( f"Unable to find relative location of {spot!r} because it has no parent" ) @@ -431,7 +433,7 @@ class Widget(DOMNode): try: return spot.parent, spot.parent.children.index(spot) except ValueError: - raise self.MountError(f"{spot!r} is not a child of {self!r}") from None + raise MountError(f"{spot!r} is not a child of {self!r}") from None def mount( self, @@ -459,7 +461,7 @@ class Widget(DOMNode): # Saying you want to mount before *and* after something is an error. if before is not None and after is not None: - raise self.MountError( + raise MountError( "Only one of `before` or `after` can be handled -- not both" ) diff --git a/tests/test_widget_mount_point.py b/tests/test_widget_mount_point.py index bcdc41dde..67a6269c3 100644 --- a/tests/test_widget_mount_point.py +++ b/tests/test_widget_mount_point.py @@ -1,6 +1,6 @@ import pytest -from textual.widget import Widget +from textual.widget import Widget, MountError class Content(Widget): @@ -36,5 +36,5 @@ def test_find_dom_spot(): # Finally, let's be sure that we get an error if, for some odd reason, # we go looking for a widget that isn't actually part of the DOM we're # looking in. - with pytest.raises(Widget.MountError): + with pytest.raises(MountError): _ = screen._find_mount_point(Widget()) diff --git a/tests/test_widget_mounting.py b/tests/test_widget_mounting.py index e1e939231..b8748a057 100644 --- a/tests/test_widget_mounting.py +++ b/tests/test_widget_mounting.py @@ -1,7 +1,7 @@ import pytest from textual.app import App -from textual.widget import Widget +from textual.widget import Widget, WidgetError, MountError from textual.widgets import Static class SelfOwn(Widget): @@ -16,7 +16,7 @@ async def test_mount_via_app() -> None: widgets = [Static(id=f"starter-{n}") for n in range( 10 )] async with App().run_test() as pilot: - with pytest.raises(Widget.WidgetError): + with pytest.raises(WidgetError): await pilot.app.mount(SelfOwn()) async with App().run_test() as pilot: @@ -92,16 +92,16 @@ async def test_mount_via_app() -> None: async with App().run_test() as pilot: # Make sure we get told off for trying to before and after. await pilot.app.mount_all(widgets) - with pytest.raises(Static.MountError): + with pytest.raises(MountError): await pilot.app.mount(Static(), before=2, after=2) async with App().run_test() as pilot: # Make sure we get told off trying to mount relative to something # that isn't actually in the DOM. await pilot.app.mount_all(widgets) - with pytest.raises(Static.MountError): + with pytest.raises(MountError): await pilot.app.mount(Static(), before=Static()) - with pytest.raises(Static.MountError): + with pytest.raises(MountError): await pilot.app.mount(Static(), after=Static()) # TODO: At the moment query_one() simply takes a query and returns the