Merge pull request #1086 from davep/drop-prenamed-mount

Drop support for anonymous vs named widget mounting
This commit is contained in:
Dave Pearson
2022-11-01 09:50:01 +00:00
committed by GitHub
4 changed files with 29 additions and 39 deletions

View File

@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.4.0] - Unreleased ## [0.4.0] - Unreleased
### Changed
- Dropped support for mounting "named" and "anonymous" widgets via
`App.mount` and `Widget.mount`. Both methods now simply take one or more
widgets as positional arguments.
### Added ### Added
- Added `init` param to reactive.watch - Added `init` param to reactive.watch

View File

@@ -822,27 +822,27 @@ class App(Generic[ReturnType], DOMNode):
self._require_stylesheet_update.add(self.screen if node is None else node) self._require_stylesheet_update.add(self.screen if node is None else node)
self.check_idle() self.check_idle()
def mount(self, *anon_widgets: Widget, **widgets: Widget) -> AwaitMount: def mount(self, *widgets: Widget) -> AwaitMount:
"""Mount widgets. Widgets specified as positional args, or keywords args. If supplied """Mount the given widgets.
as keyword args they will be assigned an id of the key.
Args:
*widgets (Widget): The widget(s) to mount.
Returns: Returns:
AwaitMount: An awaitable object that waits for widgets to be mounted. AwaitMount: An awaitable object that waits for widgets to be mounted.
""" """
mounted_widgets = self._register(self.screen, *anon_widgets, **widgets) return AwaitMount(self._register(self.screen, *widgets))
return AwaitMount(mounted_widgets)
def mount_all(self, widgets: Iterable[Widget]) -> AwaitMount: def mount_all(self, widgets: Iterable[Widget]) -> AwaitMount:
"""Mount widgets from an iterable. """Mount widgets from an iterable.
Args: Args:
widgets (Iterable[Widget]): An iterable of widgets. widgets (Iterable[Widget]): An iterable of widgets.
Returns:
AwaitMount: An awaitable object that waits for widgets to be mounted.
""" """
mounted_widgets = list(widgets) return self.mount(*widgets)
for widget in mounted_widgets:
self._register(self.screen, widget)
return AwaitMount(mounted_widgets)
def is_screen_installed(self, screen: Screen | str) -> bool: def is_screen_installed(self, screen: Screen | str) -> bool:
"""Check if a given screen has been installed. """Check if a given screen has been installed.
@@ -1300,37 +1300,33 @@ class App(Generic[ReturnType], DOMNode):
return True return True
return False return False
def _register( def _register(self, parent: DOMNode, *widgets: Widget) -> list[Widget]:
self, parent: DOMNode, *anon_widgets: Widget, **widgets: Widget
) -> list[Widget]:
"""Register widget(s) so they may receive events. """Register widget(s) so they may receive events.
Args: Args:
parent (Widget): Parent Widget. parent (DOMNode): Parent node.
*widgets: The widget(s) to register.
Returns: Returns:
list[Widget]: List of modified widgets. list[Widget]: List of modified widgets.
""" """
if not anon_widgets and not widgets:
if not widgets:
return [] return []
name_widgets: list[tuple[str | None, Widget]]
name_widgets = [*((None, widget) for widget in anon_widgets), *widgets.items()]
apply_stylesheet = self.stylesheet.apply apply_stylesheet = self.stylesheet.apply
for widget_id, widget in name_widgets: for widget in widgets:
if not isinstance(widget, Widget): if not isinstance(widget, Widget):
raise AppError(f"Can't register {widget!r}; expected a Widget instance") raise AppError(f"Can't register {widget!r}; expected a Widget instance")
if widget not in self._registry: if widget not in self._registry:
if widget_id is not None:
widget.id = widget_id
self._register_child(parent, widget) self._register_child(parent, widget)
if widget.children: if widget.children:
self._register(widget, *widget.children) self._register(widget, *widget.children)
apply_stylesheet(widget) apply_stylesheet(widget)
registered_widgets = [widget for _, widget in name_widgets] return list(widgets)
return registered_widgets
def _unregister(self, widget: Widget) -> None: def _unregister(self, widget: Widget) -> None:
"""Unregister a widget. """Unregister a widget.

View File

@@ -609,21 +609,16 @@ class DOMNode(MessagePump):
self.children._append(node) self.children._append(node)
node._attach(self) node._attach(self)
def _add_children(self, *nodes: Widget, **named_nodes: Widget) -> None: def _add_children(self, *nodes: Widget) -> None:
"""Add multiple children to this node. """Add multiple children to this node.
Args: Args:
*nodes (DOMNode): Positional args should be new DOM nodes. *nodes (DOMNode): Positional args should be new DOM nodes.
**named_nodes (DOMNode): Keyword args will be assigned the argument name as an ID.
""" """
_append = self.children._append _append = self.children._append
for node in nodes: for node in nodes:
node._attach(self) node._attach(self)
_append(node) _append(node)
for node_id, node in named_nodes.items():
node._attach(self)
_append(node)
node.id = node_id
WalkType = TypeVar("WalkType") WalkType = TypeVar("WalkType")

View File

@@ -375,23 +375,16 @@ 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
def mount(self, *anon_widgets: Widget, **widgets: Widget) -> AwaitMount: def mount(self, *widgets: Widget) -> AwaitMount:
"""Mount child widgets (making this widget a container). """Mount child widgets (making this widget a container).
Widgets may be passed as positional arguments or keyword arguments. If keyword arguments, Args:
the keys will be set as the Widget's id. *widgets (Widget): The widget(s) to mount.
Example:
```python
self.mount(Static("hello"), header=Header())
```
Returns: Returns:
AwaitMount: An awaitable object that waits for widgets to be mounted. AwaitMount: An awaitable object that waits for widgets to be mounted.
""" """
mounted_widgets = self.app._register(self, *anon_widgets, **widgets) return AwaitMount(self.app._register(self, *widgets))
return AwaitMount(mounted_widgets)
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
"""Called by Textual to create child widgets. """Called by Textual to create child widgets.