mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Hoist WidgetError and MountError to the top level of widget.py
This commit is contained in:
@@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user