[App] Add _path suffixes to PathLike constructor args

This commit is contained in:
Olivier Philippon
2022-05-04 12:18:04 +01:00
parent 3f09af3768
commit 73db7ae3ad
26 changed files with 46 additions and 51 deletions

View File

@@ -87,7 +87,7 @@ class ColorChanger(App):
self.background = f"on color({event.key})"
ColorChanger.run(log="textual.log")
ColorChanger.run(log_path="textual.log")
```
You'll notice that the `on_key` method above contains an additional `event` parameter which wasn't present on the beeper example. If the `event` argument is present, Textual will call the handler with an event object. Every event has an associated handler object, in this case it is a KeyEvent which contains additional information regarding which key was pressed.
@@ -114,7 +114,7 @@ class SimpleApp(App):
await self.view.dock(Placeholder(), Placeholder(), edge="top")
SimpleApp.run(log="textual.log")
SimpleApp.run(log_path="textual.log")
```
This app contains a single event handler `on_mount`. The mount event is sent when the app or widget is ready to start processing events, and is typically used for initialization. You may have noticed that `on_mount` is an `async` function. Since Textual is an asynchronous framework we will need this if we need to call most other methods.
@@ -137,7 +137,7 @@ await self.view.dock(Placeholder(), Placeholder(), edge="top")
You will notice that this time we are docking _two_ Placeholder objects onto the `"top"` edge. We haven't set an explicit size this time so Textual will divide the remaining size amongst the two new widgets.
The last line calls the `run` class method in the usual way, but with an argument we haven't seen before: `log="textual.log"` tells Textual to write log information to the given file. You can tail textual.log to see events being processed and other debug information.
The last line calls the `run` class method in the usual way, but with an argument we haven't seen before: `log_path="textual.log"` tells Textual to write log information to the given file. You can tail textual.log to see events being processed and other debug information.
If you run the above example, you will see something like the following:
@@ -183,7 +183,7 @@ class HoverApp(App):
await self.view.dock(*hovers, edge="top")
HoverApp.run(log="textual.log")
HoverApp.run(log_path="textual.log")
```
The `Hover` class is a custom widget which displays a panel containing the classic text "Hello World". The first line in the Hover class may seem a little mysterious at this point:

View File

@@ -7,4 +7,4 @@ class ColorChanger(App):
self.background = f"on color({event.key})"
ColorChanger.run(log="textual.log")
ColorChanger.run(log_path="textual.log")

View File

@@ -29,4 +29,4 @@ class HoverApp(App):
await self.screen.dock(*hovers, edge="top")
HoverApp.run(log="textual.log")
HoverApp.run(log_path="textual.log")

View File

@@ -12,4 +12,4 @@ class SimpleApp(App):
await self.screen.dock(Placeholder(), Placeholder(), edge="top")
SimpleApp.run(log="textual.log")
SimpleApp.run(log_path="textual.log")

View File

@@ -143,9 +143,9 @@ class BasicApp(App):
sandbox_folder = Path(__file__).parent
app = BasicApp(
css_file=sandbox_folder / "basic.css",
css_path=sandbox_folder / "basic.css",
watch_css=True,
log=sandbox_folder / "textual.log",
log_path=sandbox_folder / "basic.log",
log_verbosity=0,
)

View File

@@ -35,4 +35,4 @@ class SmoothApp(App):
# self.set_timer(10, lambda: self.action("quit"))
SmoothApp.run(log="textual.log", log_verbosity=2)
SmoothApp.run(log_path="textual.log", log_verbosity=2)

View File

@@ -30,4 +30,4 @@ class MyApp(App):
await self.call_later(add_content)
MyApp.run(title="Simple App", log="textual.log")
MyApp.run(title="Simple App", log_path="textual.log")

View File

@@ -55,4 +55,4 @@ class BordersApp(App):
self.mount(borders=borders_view)
BordersApp.run(css_file="borders.css", log="textual.log")
BordersApp.run(css_path="borders.css", log_path="textual.log")

View File

@@ -212,4 +212,4 @@ class CalculatorApp(App):
await self.screen.dock(Calculator())
CalculatorApp.run(title="Calculator Test", log="textual.log")
CalculatorApp.run(title="Calculator Test", log_path="textual.log")

View File

@@ -67,4 +67,4 @@ class MyApp(App):
# Run our app class
MyApp.run(title="Code Viewer", log="textual.log")
MyApp.run(title="Code Viewer", log_path="textual.log")

View File

@@ -42,4 +42,4 @@ class EasingApp(App):
self.side = not self.side
EasingApp().run(log="textual.log")
EasingApp().run(log_path="textual.log")

View File

@@ -31,4 +31,4 @@ class GridTest(App):
)
GridTest.run(title="Grid Test", log="textual.log")
GridTest.run(title="Grid Test", log_path="textual.log")

View File

@@ -19,4 +19,4 @@ class GridTest(App):
grid.place(*placeholders, center=Placeholder())
GridTest.run(title="Grid Test", log="textual.log")
GridTest.run(title="Grid Test", log_path="textual.log")

View File

@@ -48,4 +48,4 @@ class MyApp(App):
await self.call_later(get_markdown, "richreadme.md")
MyApp.run(title="Simple App", log="textual.log")
MyApp.run(title="Simple App", log_path="textual.log")

View File

@@ -22,4 +22,4 @@ class AlignApp(App):
self.log(self.screen.tree)
AlignApp.run(css_file="align.css", log="textual.log", watch_css=True)
AlignApp.run(css_path="align.css", log_path="textual.log", watch_css=True)

View File

@@ -1,6 +1,3 @@
from pathlib import Path
from rich.align import Align
from rich.console import RenderableType
from rich.syntax import Syntax
from rich.text import Text
@@ -141,11 +138,10 @@ class BasicApp(App):
self.panic(self.tree)
sandbox_folder = Path(__file__).parent
app = BasicApp(
css_file=sandbox_folder / "basic.css",
css_path="basic.css",
watch_css=True,
log=sandbox_folder / "textual.log",
log_path="textual.log",
)
if __name__ == "__main__":

View File

@@ -5,7 +5,6 @@ from textual import layout
class ButtonsApp(App[str]):
def compose(self) -> ComposeResult:
yield layout.Vertical(
Button("foo", id="foo"),
@@ -19,7 +18,7 @@ class ButtonsApp(App[str]):
self.exit(event.button.id)
app = ButtonsApp(log="textual.log", log_verbosity=2)
app = ButtonsApp(log_path="textual.log", log_verbosity=2)
if __name__ == "__main__":
result = app.run()

View File

@@ -34,4 +34,4 @@ class BasicApp(App):
self.panic(self.tree)
BasicApp.run(css_file="dev_sandbox.scss", watch_css=True, log="textual.log")
BasicApp.run(css_path="dev_sandbox.scss", watch_css=True, log_path="textual.log")

View File

@@ -33,4 +33,4 @@ class BasicApp(App):
self.log(header.styles)
BasicApp.run(css_file="local_styles.css", log="textual.log")
BasicApp.run(css_path="local_styles.css", log_path="textual.log")

View File

@@ -144,4 +144,4 @@ class BasicApp(App):
self.mount(example.widget)
BasicApp.run(css_file="tabs.scss", watch_css=True, log="textual.log")
BasicApp.run(css_path="tabs.scss", watch_css=True, log_path="textual.log")

View File

@@ -83,7 +83,7 @@ class BasicApp(App):
self.focused.styles.border_top = ("solid", "invalid-color")
app = BasicApp(css_file="uber.css", log="textual.log", log_verbosity=1)
app = BasicApp(css_path="uber.css", log_path="textual.log", log_verbosity=1)
if __name__ == "__main__":
app.run()

View File

@@ -106,20 +106,20 @@ class App(Generic[ReturnType], DOMNode):
def __init__(
self,
driver_class: Type[Driver] | None = None,
log: str | PurePath = "",
log_path: str | PurePath = "",
log_verbosity: int = 1,
title: str = "Textual Application",
css_file: str | PurePath | None = None,
css_path: str | PurePath | None = None,
watch_css: bool = True,
):
"""Textual application base class
Args:
driver_class (Type[Driver] | None, optional): Driver class or ``None`` to auto-detect. Defaults to None.
log (str | PurePath, optional): Path to log file, or "" to disable. Defaults to "".
log_path (str | PurePath, optional): Path to log file, or "" to disable. Defaults to "".
log_verbosity (int, optional): Log verbosity from 0-3. Defaults to 1.
title (str, optional): Default title of the application. Defaults to "Textual Application".
css_file (str | PurePath | None, optional): Path to CSS or ``None`` for no CSS file. Defaults to None.
css_path (str | PurePath | None, optional): Path to CSS or ``None`` for no CSS file. Defaults to None.
watch_css (bool, optional): Watch CSS for changes. Defaults to True.
"""
# N.B. This must be done *before* we call the parent constructor, because MessagePump's
@@ -151,8 +151,8 @@ class App(Generic[ReturnType], DOMNode):
self._log_console: Console | None = None
self._log_file: TextIO | None = None
if log:
self._log_file = open(log, "wt")
if log_path:
self._log_file = open(log_path, "wt")
self._log_console = Console(
file=self._log_file,
markup=False,
@@ -171,10 +171,10 @@ class App(Generic[ReturnType], DOMNode):
self.stylesheet = Stylesheet(variables=self.get_css_variables())
self._require_styles_update = False
self.css_file = css_file
self.css_path = css_path
self.css_monitor = (
FileMonitor(css_file, self._on_css_change)
if (watch_css and css_file)
FileMonitor(css_path, self._on_css_change)
if (watch_css and css_path)
else None
)
@@ -450,13 +450,13 @@ class App(Generic[ReturnType], DOMNode):
async def _on_css_change(self) -> None:
"""Called when the CSS changes (if watch_css is True)."""
if self.css_file is not None:
if self.css_path is not None:
try:
time = perf_counter()
self.stylesheet.read(self.css_file)
self.stylesheet.read(self.css_path)
elapsed = (perf_counter() - time) * 1000
self.log(f"loaded {self.css_file} in {elapsed:.0f}ms")
self.log(f"loaded {self.css_path} in {elapsed:.0f}ms")
except Exception as error:
# TODO: Catch specific exceptions
self.console.bell()
@@ -647,8 +647,8 @@ class App(Generic[ReturnType], DOMNode):
except DevtoolsConnectionError:
self.log(f"Couldn't connect to devtools ({self.devtools.url})")
try:
if self.css_file is not None:
self.stylesheet.read(self.css_file)
if self.css_path is not None:
self.stylesheet.read(self.css_path)
if self.CSS is not None:
self.stylesheet.add_source(
self.CSS, path=f"<{self.__class__.__name__}>"

View File

@@ -36,8 +36,8 @@ def _check_selectors(selectors: list[Selector], node: DOMNode) -> bool:
DESCENDENT = CombinatorType.DESCENDENT
css_path = node.css_path
path_count = len(css_path)
css_path_nodes = node.css_path_nodes
path_count = len(css_path_nodes)
selector_count = len(selectors)
stack: list[tuple[int, int]] = [(0, 0)]
@@ -51,7 +51,7 @@ def _check_selectors(selectors: list[Selector], node: DOMNode) -> bool:
if selector_index == selector_count or node_index == path_count:
pop()
else:
path_node = css_path[node_index]
path_node = css_path_nodes[node_index]
selector = selectors[selector_index]
if selector.combinator == DESCENDENT:
# Find a matching descendent

View File

@@ -167,7 +167,7 @@ class DOMNode(MessagePump):
return self.__class__.__name__.lower()
@property
def css_path(self) -> list[DOMNode]:
def css_path_nodes(self) -> list[DOMNode]:
"""A list of nodes from the root to this node, forming a "path".
Returns:

View File

@@ -132,4 +132,4 @@ if __name__ == "__main__":
async def on_mount(self, event: events.Mount) -> None:
await self.screen.dock(DirectoryTree("/Users/willmcgugan/projects"))
TreeApp.run(log="textual.log")
TreeApp(log_path="textual.log").run()

View File

@@ -328,4 +328,4 @@ if __name__ == "__main__":
else:
await message.node.toggle()
TreeApp.run(log="textual.log")
TreeApp(log_path="textual.log").run()