mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
[API] Start accepting PathLike objects here and there
This commit is contained in:
@@ -141,9 +141,12 @@ class BasicApp(App):
|
||||
self.panic(self.tree)
|
||||
|
||||
|
||||
css_file = Path(__file__).parent / "basic.css"
|
||||
sandbox_folder = Path(__file__).parent
|
||||
app = BasicApp(
|
||||
css_file=str(css_file), watch_css=True, log="textual.log", log_verbosity=0
|
||||
css_file=sandbox_folder / "basic.css",
|
||||
watch_css=True,
|
||||
log=sandbox_folder / "textual.log",
|
||||
log_verbosity=0,
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -141,8 +141,12 @@ class BasicApp(App):
|
||||
self.panic(self.tree)
|
||||
|
||||
|
||||
css_file = Path(__file__).parent / "basic.css"
|
||||
app = BasicApp(css_file=str(css_file), watch_css=True, log="textual.log")
|
||||
sandbox_folder = Path(__file__).parent
|
||||
app = BasicApp(
|
||||
css_file=sandbox_folder / "basic.css",
|
||||
watch_css=True,
|
||||
log=sandbox_folder / "textual.log",
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
|
||||
@@ -7,6 +7,7 @@ import platform
|
||||
import sys
|
||||
import warnings
|
||||
from contextlib import redirect_stdout
|
||||
from pathlib import PurePath
|
||||
from time import perf_counter
|
||||
from typing import (
|
||||
Any,
|
||||
@@ -105,20 +106,20 @@ class App(Generic[ReturnType], DOMNode):
|
||||
def __init__(
|
||||
self,
|
||||
driver_class: Type[Driver] | None = None,
|
||||
log: str = "",
|
||||
log: str | PurePath = "",
|
||||
log_verbosity: int = 1,
|
||||
title: str = "Textual Application",
|
||||
css_file: str | None = None,
|
||||
css_file: 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, optional): Path to log file, or "" to disable. Defaults to "".
|
||||
log (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 | None, optional): Path to CSS or ``None`` for no CSS file. Defaults to None.
|
||||
css_file (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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import lru_cache
|
||||
from pathlib import PurePath
|
||||
from typing import Iterator, Iterable
|
||||
|
||||
from rich import print
|
||||
@@ -305,7 +306,7 @@ def substitute_references(
|
||||
|
||||
|
||||
def parse(
|
||||
css: str, path: str, variables: dict[str, str] | None = None
|
||||
css: str, path: str | PurePath, variables: dict[str, str] | None = None
|
||||
) -> Iterable[RuleSet]:
|
||||
"""Parse CSS by tokenizing it, performing variable substitution,
|
||||
and generating rule sets from it.
|
||||
|
||||
@@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
import os
|
||||
from collections import defaultdict
|
||||
from operator import itemgetter
|
||||
from pathlib import Path
|
||||
from pathlib import Path, PurePath
|
||||
from typing import cast, Iterable
|
||||
|
||||
import rich.repr
|
||||
@@ -149,13 +149,13 @@ class Stylesheet:
|
||||
"""
|
||||
self.variables = variables
|
||||
|
||||
def _parse_rules(self, css: str, path: str) -> list[RuleSet]:
|
||||
def _parse_rules(self, css: str, path: str | PurePath) -> list[RuleSet]:
|
||||
"""Parse CSS and return rules.
|
||||
|
||||
|
||||
Args:
|
||||
css (str): String containing Textual CSS.
|
||||
path (str): Path to CSS or unique identifier
|
||||
path (str | PurePath): Path to CSS or unique identifier
|
||||
|
||||
Raises:
|
||||
StylesheetError: If the CSS is invalid.
|
||||
@@ -171,11 +171,11 @@ class Stylesheet:
|
||||
raise StylesheetError(f"failed to parse css; {error}")
|
||||
return rules
|
||||
|
||||
def read(self, filename: str) -> None:
|
||||
def read(self, filename: str | PurePath) -> None:
|
||||
"""Read Textual CSS file.
|
||||
|
||||
Args:
|
||||
filename (str): filename of CSS.
|
||||
filename (str | PurePath): filename of CSS.
|
||||
|
||||
Raises:
|
||||
StylesheetError: If the CSS could not be read.
|
||||
@@ -188,15 +188,16 @@ class Stylesheet:
|
||||
path = os.path.abspath(filename)
|
||||
except Exception as error:
|
||||
raise StylesheetError(f"unable to read {filename!r}; {error}")
|
||||
self.source[path] = css
|
||||
self.source[str(path)] = css
|
||||
self._require_parse = True
|
||||
|
||||
def add_source(self, css: str, path: str | None = None) -> None:
|
||||
def add_source(self, css: str, path: str | PurePath | None = None) -> None:
|
||||
"""Parse CSS from a string.
|
||||
|
||||
Args:
|
||||
css (str): String with CSS source.
|
||||
path (str, optional): The path of the source if a file, or some other identifier. Defaults to "".
|
||||
path (str | PurePath, optional): The path of the source if a file, or some other identifier.
|
||||
Defaults to None.
|
||||
|
||||
Raises:
|
||||
StylesheetError: If the CSS could not be read.
|
||||
@@ -205,6 +206,8 @@ class Stylesheet:
|
||||
|
||||
if path is None:
|
||||
path = str(hash(css))
|
||||
elif isinstance(path, PurePath):
|
||||
path = str(css)
|
||||
if path in self.source and self.source[path] == css:
|
||||
# Path already in source, and CSS is identical
|
||||
return
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from pathlib import PurePath
|
||||
from typing import Iterable
|
||||
|
||||
from textual.css.tokenizer import Expect, Tokenizer, Token
|
||||
@@ -136,7 +137,7 @@ class TokenizerState:
|
||||
"declaration_set_end": expect_root_scope,
|
||||
}
|
||||
|
||||
def __call__(self, code: str, path: str) -> Iterable[Token]:
|
||||
def __call__(self, code: str, path: str | PurePath) -> Iterable[Token]:
|
||||
tokenizer = Tokenizer(code, path=path)
|
||||
expect = self.EXPECT
|
||||
get_token = tokenizer.get_token
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from pathlib import PurePath
|
||||
from typing import NamedTuple
|
||||
|
||||
from rich.console import Group, RenderableType
|
||||
@@ -148,8 +149,8 @@ class Token(NamedTuple):
|
||||
|
||||
|
||||
class Tokenizer:
|
||||
def __init__(self, text: str, path: str = "") -> None:
|
||||
self.path = path
|
||||
def __init__(self, text: str, path: str | PurePath = "") -> None:
|
||||
self.path = str(path)
|
||||
self.code = text
|
||||
self.lines = text.splitlines(keepends=True)
|
||||
self.line_no = 0
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
from __future__ import annotations
|
||||
import os
|
||||
from pathlib import PurePath
|
||||
from typing import Callable
|
||||
|
||||
import rich.repr
|
||||
@@ -8,7 +10,7 @@ from ._callback import invoke
|
||||
|
||||
@rich.repr.auto
|
||||
class FileMonitor:
|
||||
def __init__(self, path: str, callback: Callable) -> None:
|
||||
def __init__(self, path: str | PurePath, callback: Callable) -> None:
|
||||
self.path = path
|
||||
self.callback = callback
|
||||
self._modified = self._get_modified()
|
||||
|
||||
Reference in New Issue
Block a user