mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
lazy parse_rules
This commit is contained in:
@@ -101,17 +101,19 @@ class StylesheetErrors:
|
||||
@rich.repr.auto
|
||||
class Stylesheet:
|
||||
def __init__(self, *, variables: dict[str, str] | None = None) -> None:
|
||||
self._rules: list[RuleSet] | None = None
|
||||
self._rules: list[RuleSet] = []
|
||||
self.variables = variables or {}
|
||||
self.source: dict[str, str] = {}
|
||||
self._require_parse = False
|
||||
|
||||
def __rich_repr__(self) -> rich.repr.Result:
|
||||
yield self.rules
|
||||
|
||||
@property
|
||||
def rules(self) -> list[RuleSet]:
|
||||
if self._rules is None:
|
||||
if self._require_parse:
|
||||
self.parse()
|
||||
self._require_parse = False
|
||||
assert self._rules is not None
|
||||
return self._rules
|
||||
|
||||
@@ -171,7 +173,7 @@ class Stylesheet:
|
||||
except Exception as error:
|
||||
raise StylesheetError(f"unable to read {filename!r}; {error}")
|
||||
self.source[path] = css
|
||||
self._rules = None
|
||||
self._require_parse = True
|
||||
|
||||
def add_source(self, css: str, path: str | None = None) -> None:
|
||||
"""Parse CSS from a string.
|
||||
@@ -192,7 +194,7 @@ class Stylesheet:
|
||||
return
|
||||
|
||||
self.source[path] = css
|
||||
self._rules = None
|
||||
self._require_parse = True
|
||||
|
||||
def parse(self) -> None:
|
||||
"""Parse the source in the stylesheet.
|
||||
@@ -208,6 +210,7 @@ class Stylesheet:
|
||||
raise StylesheetParseError(self.error_renderable)
|
||||
add_rules(css_rules)
|
||||
self._rules = rules
|
||||
self._require_parse = False
|
||||
|
||||
def reparse(self) -> None:
|
||||
"""Re-parse source, applying new variables.
|
||||
@@ -221,7 +224,8 @@ class Stylesheet:
|
||||
stylesheet = Stylesheet(variables=self.variables)
|
||||
for path, css in self.source.items():
|
||||
stylesheet.add_source(css, path)
|
||||
self._rules = None
|
||||
stylesheet.parse()
|
||||
self.rules = stylesheet.rules
|
||||
self.source = stylesheet.source
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -875,6 +875,7 @@ class TestParseLayout:
|
||||
stylesheet = Stylesheet()
|
||||
with pytest.raises(StylesheetParseError) as ex:
|
||||
stylesheet.add_source(css)
|
||||
stylesheet.parse()
|
||||
|
||||
assert ex.value.errors is not None
|
||||
|
||||
@@ -1033,8 +1034,10 @@ class TestParseTransition:
|
||||
stylesheet = Stylesheet()
|
||||
with pytest.raises(StylesheetParseError) as ex:
|
||||
stylesheet.add_source(css)
|
||||
stylesheet.parse()
|
||||
|
||||
stylesheet_errors = stylesheet.rules[0].errors
|
||||
rules = stylesheet._parse_rules(css, "foo")
|
||||
stylesheet_errors = rules[0].errors
|
||||
|
||||
assert len(stylesheet_errors) == 1
|
||||
assert stylesheet_errors[0][0].value == invalid_func_name
|
||||
@@ -1067,7 +1070,9 @@ class TestParseOpacity:
|
||||
|
||||
with pytest.raises(StylesheetParseError):
|
||||
stylesheet.add_source(css)
|
||||
assert stylesheet.rules[0].errors
|
||||
stylesheet.parse()
|
||||
rules = stylesheet._parse_rules(css, "foo")
|
||||
assert rules[0].errors
|
||||
|
||||
|
||||
class TestParseMargin:
|
||||
|
||||
@@ -43,6 +43,7 @@ def test_color_property_parsing(css_value, expectation, expected_color):
|
||||
|
||||
with expectation:
|
||||
stylesheet.add_source(css)
|
||||
stylesheet.parse()
|
||||
|
||||
if expected_color:
|
||||
css_rule = stylesheet.rules[0]
|
||||
|
||||
Reference in New Issue
Block a user