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

View File

@@ -609,21 +609,16 @@ class DOMNode(MessagePump):
self.children._append(node)
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.
Args:
*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
for node in nodes:
node._attach(self)
_append(node)
for node_id, node in named_nodes.items():
node._attach(self)
_append(node)
node.id = node_id
WalkType = TypeVar("WalkType")

View File

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