Hoist WidgetError and MountError to the top level of widget.py

This commit is contained in:
Dave Pearson
2022-11-08 13:53:22 +00:00
parent fbbd8a2678
commit 0324fb90d1
3 changed files with 20 additions and 18 deletions

View File

@@ -147,6 +147,14 @@ class RenderCache(NamedTuple):
lines: Lines 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 @rich.repr.auto
class Widget(DOMNode): class Widget(DOMNode):
""" """
@@ -189,9 +197,6 @@ class Widget(DOMNode):
hover_style: Reactive[Style] = Reactive(Style, repaint=False) hover_style: Reactive[Style] = Reactive(Style, repaint=False)
highlight_link_id: Reactive[str] = Reactive("") highlight_link_id: Reactive[str] = Reactive("")
class WidgetError(Exception):
"""Base widget error."""
def __init__( def __init__(
self, self,
*children: Widget, *children: Widget,
@@ -238,7 +243,7 @@ class Widget(DOMNode):
) )
if self in children: 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) self._add_children(*children)
@@ -381,9 +386,6 @@ class Widget(DOMNode):
if self._scrollbar_corner is not None: if self._scrollbar_corner is not None:
yield self._scrollbar_corner 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]: def _find_mount_point(self, spot: int | str | "Widget") -> tuple["Widget", int]:
"""Attempt to locate the point where the caller wants to mount something. """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. tuple[Widget, int]: The parent and the location in its child list.
Raises: 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: 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 # 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. # mounting decisions if it doesn't have a parent.
if spot.parent is None: if spot.parent is None:
raise self.MountError( raise MountError(
f"Unable to find relative location of {spot!r} because it has no parent" f"Unable to find relative location of {spot!r} because it has no parent"
) )
@@ -431,7 +433,7 @@ class Widget(DOMNode):
try: try:
return spot.parent, spot.parent.children.index(spot) return spot.parent, spot.parent.children.index(spot)
except ValueError: 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( def mount(
self, self,
@@ -459,7 +461,7 @@ class Widget(DOMNode):
# Saying you want to mount before *and* after something is an error. # Saying you want to mount before *and* after something is an error.
if before is not None and after is not None: 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" "Only one of `before` or `after` can be handled -- not both"
) )

View File

@@ -1,6 +1,6 @@
import pytest import pytest
from textual.widget import Widget from textual.widget import Widget, MountError
class Content(Widget): 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, # 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 # we go looking for a widget that isn't actually part of the DOM we're
# looking in. # looking in.
with pytest.raises(Widget.MountError): with pytest.raises(MountError):
_ = screen._find_mount_point(Widget()) _ = screen._find_mount_point(Widget())

View File

@@ -1,7 +1,7 @@
import pytest import pytest
from textual.app import App from textual.app import App
from textual.widget import Widget from textual.widget import Widget, WidgetError, MountError
from textual.widgets import Static from textual.widgets import Static
class SelfOwn(Widget): 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 )] widgets = [Static(id=f"starter-{n}") for n in range( 10 )]
async with App().run_test() as pilot: async with App().run_test() as pilot:
with pytest.raises(Widget.WidgetError): with pytest.raises(WidgetError):
await pilot.app.mount(SelfOwn()) await pilot.app.mount(SelfOwn())
async with App().run_test() as pilot: 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: async with App().run_test() as pilot:
# Make sure we get told off for trying to before and after. # Make sure we get told off for trying to before and after.
await pilot.app.mount_all(widgets) await pilot.app.mount_all(widgets)
with pytest.raises(Static.MountError): with pytest.raises(MountError):
await pilot.app.mount(Static(), before=2, after=2) await pilot.app.mount(Static(), before=2, after=2)
async with App().run_test() as pilot: async with App().run_test() as pilot:
# Make sure we get told off trying to mount relative to something # Make sure we get told off trying to mount relative to something
# that isn't actually in the DOM. # that isn't actually in the DOM.
await pilot.app.mount_all(widgets) await pilot.app.mount_all(widgets)
with pytest.raises(Static.MountError): with pytest.raises(MountError):
await pilot.app.mount(Static(), before=Static()) await pilot.app.mount(Static(), before=Static())
with pytest.raises(Static.MountError): with pytest.raises(MountError):
await pilot.app.mount(Static(), after=Static()) await pilot.app.mount(Static(), after=Static())
# TODO: At the moment query_one() simply takes a query and returns the # TODO: At the moment query_one() simply takes a query and returns the