mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Merge pull request #1759 from Textualize/typing-fix-9-feb-2023
typing fixes
This commit is contained in:
2315
poetry.lock
generated
2315
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -69,6 +69,7 @@ syrupy = "^3.0.0"
|
||||
mkdocs-rss-plugin = "^1.5.0"
|
||||
httpx = "^0.23.1"
|
||||
msgpack-types = "^0.2.0"
|
||||
types-setuptools = "^67.2.0.1"
|
||||
|
||||
[tool.black]
|
||||
includes = "src"
|
||||
|
||||
@@ -191,7 +191,7 @@ BORDER_LOCATIONS: dict[
|
||||
|
||||
INVISIBLE_EDGE_TYPES = cast("frozenset[EdgeType]", frozenset(("", "none", "hidden")))
|
||||
|
||||
BorderValue: TypeAlias = Tuple[EdgeType, Union[str, Color, Style]]
|
||||
BorderValue: TypeAlias = Tuple[EdgeType, Color]
|
||||
|
||||
BoxSegments: TypeAlias = Tuple[
|
||||
Tuple[Segment, Segment, Segment],
|
||||
|
||||
@@ -10,11 +10,12 @@ when setting and getting.
|
||||
from __future__ import annotations
|
||||
|
||||
from operator import attrgetter
|
||||
from typing import TYPE_CHECKING, Generic, Iterable, NamedTuple, TypeVar, cast
|
||||
from typing import TYPE_CHECKING, Generic, Iterable, NamedTuple, Sequence, TypeVar, cast
|
||||
|
||||
import rich.errors
|
||||
import rich.repr
|
||||
from rich.style import Style
|
||||
from typing_extensions import TypeAlias
|
||||
|
||||
from .._border import normalize_border_value
|
||||
from ..color import Color, ColorParseError
|
||||
@@ -51,7 +52,7 @@ if TYPE_CHECKING:
|
||||
|
||||
from .types import AlignHorizontal, AlignVertical, DockEdge, EdgeType
|
||||
|
||||
BorderDefinition = (
|
||||
BorderDefinition: TypeAlias = (
|
||||
"Sequence[tuple[EdgeType, str | Color] | None] | tuple[EdgeType, str | Color]"
|
||||
)
|
||||
|
||||
@@ -153,7 +154,7 @@ class ScalarProperty:
|
||||
Returns:
|
||||
The Scalar object or ``None`` if it's not set.
|
||||
"""
|
||||
return obj.get_rule(self.name)
|
||||
return cast("Scalar | None", obj.get_rule(self.name))
|
||||
|
||||
def __set__(
|
||||
self, obj: StylesBase, value: float | int | Scalar | str | None
|
||||
@@ -233,7 +234,7 @@ class ScalarListProperty:
|
||||
def __get__(
|
||||
self, obj: StylesBase, objtype: type[StylesBase] | None = None
|
||||
) -> tuple[Scalar, ...] | None:
|
||||
return obj.get_rule(self.name)
|
||||
return cast("tuple[Scalar, ...]", obj.get_rule(self.name))
|
||||
|
||||
def __set__(
|
||||
self, obj: StylesBase, value: str | Iterable[str | float] | None
|
||||
@@ -289,7 +290,10 @@ class BoxProperty:
|
||||
A ``tuple[EdgeType, Style]`` containing the string type of the box and
|
||||
it's style. Example types are "rounded", "solid", and "dashed".
|
||||
"""
|
||||
return obj.get_rule(self.name) or ("", self._default_color)
|
||||
return cast(
|
||||
"tuple[EdgeType, Color]",
|
||||
obj.get_rule(self.name) or ("", self._default_color),
|
||||
)
|
||||
|
||||
def __set__(self, obj: Styles, border: tuple[EdgeType, str | Color] | None):
|
||||
"""Set the box property.
|
||||
@@ -452,7 +456,7 @@ class BorderProperty:
|
||||
check_refresh()
|
||||
return
|
||||
if isinstance(border, tuple) and len(border) == 2:
|
||||
_border = normalize_border_value(border)
|
||||
_border = normalize_border_value(border) # type: ignore
|
||||
setattr(obj, top, _border)
|
||||
setattr(obj, right, _border)
|
||||
setattr(obj, bottom, _border)
|
||||
@@ -462,15 +466,15 @@ class BorderProperty:
|
||||
|
||||
count = len(border)
|
||||
if count == 1:
|
||||
_border = normalize_border_value(border[0])
|
||||
_border = normalize_border_value(border[0]) # type: ignore
|
||||
setattr(obj, top, _border)
|
||||
setattr(obj, right, _border)
|
||||
setattr(obj, bottom, _border)
|
||||
setattr(obj, left, _border)
|
||||
elif count == 2:
|
||||
_border1, _border2 = (
|
||||
normalize_border_value(border[0]),
|
||||
normalize_border_value(border[1]),
|
||||
normalize_border_value(border[0]), # type: ignore
|
||||
normalize_border_value(border[1]), # type: ignore
|
||||
)
|
||||
setattr(obj, top, _border1)
|
||||
setattr(obj, bottom, _border1)
|
||||
@@ -478,10 +482,10 @@ class BorderProperty:
|
||||
setattr(obj, left, _border2)
|
||||
elif count == 4:
|
||||
_border1, _border2, _border3, _border4 = (
|
||||
normalize_border_value(border[0]),
|
||||
normalize_border_value(border[1]),
|
||||
normalize_border_value(border[2]),
|
||||
normalize_border_value(border[3]),
|
||||
normalize_border_value(border[0]), # type: ignore
|
||||
normalize_border_value(border[1]), # type: ignore
|
||||
normalize_border_value(border[2]), # type: ignore
|
||||
normalize_border_value(border[3]), # type: ignore
|
||||
)
|
||||
setattr(obj, top, _border1)
|
||||
setattr(obj, right, _border2)
|
||||
@@ -513,7 +517,7 @@ class SpacingProperty:
|
||||
Returns:
|
||||
The Spacing. If unset, returns the null spacing ``(0, 0, 0, 0)``.
|
||||
"""
|
||||
return obj.get_rule(self.name, NULL_SPACING)
|
||||
return cast(Spacing, obj.get_rule(self.name, NULL_SPACING))
|
||||
|
||||
def __set__(self, obj: StylesBase, spacing: SpacingDimensions | None):
|
||||
"""Set the Spacing.
|
||||
@@ -594,7 +598,7 @@ class LayoutProperty:
|
||||
Returns:
|
||||
The ``Layout`` object.
|
||||
"""
|
||||
return obj.get_rule(self.name)
|
||||
return cast("Layout | None", obj.get_rule(self.name))
|
||||
|
||||
def __set__(self, obj: StylesBase, layout: str | Layout | None):
|
||||
"""
|
||||
@@ -648,7 +652,7 @@ class OffsetProperty:
|
||||
The ``ScalarOffset`` indicating the adjustment that
|
||||
will be made to widget position prior to it being rendered.
|
||||
"""
|
||||
return obj.get_rule(self.name, NULL_SCALAR)
|
||||
return cast("ScalarOffset", obj.get_rule(self.name, NULL_SCALAR))
|
||||
|
||||
def __set__(
|
||||
self, obj: StylesBase, offset: tuple[int | str, int | str] | ScalarOffset | None
|
||||
@@ -734,7 +738,7 @@ class StringEnumProperty:
|
||||
Returns:
|
||||
The string property value.
|
||||
"""
|
||||
return obj.get_rule(self.name, self._default)
|
||||
return cast(str, obj.get_rule(self.name, self._default))
|
||||
|
||||
def _before_refresh(self, obj: StylesBase, value: str | None) -> None:
|
||||
"""Do any housekeeping before asking for a layout refresh after a value change."""
|
||||
@@ -795,7 +799,7 @@ class NameProperty:
|
||||
Returns:
|
||||
The name.
|
||||
"""
|
||||
return obj.get_rule(self.name, "")
|
||||
return cast(str, obj.get_rule(self.name, ""))
|
||||
|
||||
def __set__(self, obj: StylesBase, name: str | None):
|
||||
"""Set the name property.
|
||||
@@ -929,7 +933,7 @@ class StyleFlagsProperty:
|
||||
Returns:
|
||||
The ``Style`` object.
|
||||
"""
|
||||
return obj.get_rule(self.name, Style.null())
|
||||
return cast(Style, obj.get_rule(self.name, Style.null()))
|
||||
|
||||
def __set__(self, obj: StylesBase, style_flags: Style | str | None):
|
||||
"""Set the style using a style flag string.
|
||||
@@ -992,7 +996,7 @@ class TransitionsProperty:
|
||||
e.g. ``{"offset": Transition(...), ...}``. If no transitions have been set, an empty ``dict``
|
||||
is returned.
|
||||
"""
|
||||
return obj.get_rule("transitions", {})
|
||||
return cast("dict[str, Transition]", obj.get_rule("transitions", {}))
|
||||
|
||||
def __set__(self, obj: Styles, transitions: dict[str, Transition] | None) -> None:
|
||||
_rich_traceback_omit = True
|
||||
|
||||
@@ -113,7 +113,6 @@ class StylesBuilder:
|
||||
suggested_property_name=suggested_property_name,
|
||||
),
|
||||
)
|
||||
return
|
||||
|
||||
tokens = declaration.tokens
|
||||
|
||||
@@ -182,7 +181,13 @@ class StylesBuilder:
|
||||
"""
|
||||
|
||||
if len(tokens) != 1:
|
||||
string_enum_help_text(name, valid_values=list(valid_values), context="css"),
|
||||
self.error(
|
||||
name,
|
||||
tokens[0],
|
||||
string_enum_help_text(
|
||||
name, valid_values=list(valid_values), context="css"
|
||||
),
|
||||
)
|
||||
|
||||
token = tokens[0]
|
||||
token_name, value, _, _, location, _ = token
|
||||
@@ -239,7 +244,7 @@ class StylesBuilder:
|
||||
return
|
||||
if len(tokens) == 1:
|
||||
try:
|
||||
self.styles._rules[name.replace("-", "_")] = Scalar.parse(
|
||||
self.styles._rules[name.replace("-", "_")] = Scalar.parse( # type: ignore
|
||||
tokens[0].value
|
||||
)
|
||||
except ScalarParseError:
|
||||
@@ -390,7 +395,7 @@ class StylesBuilder:
|
||||
name, num_values_supplied=len(space), context="css"
|
||||
),
|
||||
)
|
||||
self.styles._rules[name] = Spacing.unpack(cast(SpacingDimensions, tuple(space)))
|
||||
self.styles._rules[name] = Spacing.unpack(cast(SpacingDimensions, tuple(space))) # type: ignore
|
||||
|
||||
def _process_space_partial(self, name: str, tokens: list[Token]) -> None:
|
||||
"""Process granular margin / padding declarations."""
|
||||
@@ -418,7 +423,7 @@ class StylesBuilder:
|
||||
spacing_list = list(current_spacing)
|
||||
spacing_list[_EDGE_SPACING_MAP[edge]] = space
|
||||
|
||||
self.styles._rules[style_name] = Spacing(*spacing_list)
|
||||
self.styles._rules[style_name] = Spacing(*spacing_list) # type: ignore
|
||||
|
||||
process_padding = _process_space
|
||||
process_margin = _process_space
|
||||
@@ -444,7 +449,7 @@ class StylesBuilder:
|
||||
token_name, value, _, _, _, _ = token
|
||||
if token_name == "token":
|
||||
if value in VALID_BORDER:
|
||||
border_type = value
|
||||
border_type = value # type: ignore
|
||||
else:
|
||||
try:
|
||||
border_color = Color.parse(value)
|
||||
@@ -464,7 +469,7 @@ class StylesBuilder:
|
||||
|
||||
def _process_border_edge(self, edge: str, name: str, tokens: list[Token]) -> None:
|
||||
border = self._parse_border(name, tokens)
|
||||
self.styles._rules[f"border_{edge}"] = border
|
||||
self.styles._rules[f"border_{edge}"] = border # type: ignore
|
||||
|
||||
def process_border(self, name: str, tokens: list[Token]) -> None:
|
||||
border = self._parse_border(name, tokens)
|
||||
@@ -486,7 +491,7 @@ class StylesBuilder:
|
||||
|
||||
def _process_outline(self, edge: str, name: str, tokens: list[Token]) -> None:
|
||||
border = self._parse_border(name, tokens)
|
||||
self.styles._rules[f"outline_{edge}"] = border
|
||||
self.styles._rules[f"outline_{edge}"] = border # type: ignore
|
||||
|
||||
def process_outline(self, name: str, tokens: list[Token]) -> None:
|
||||
border = self._parse_border(name, tokens)
|
||||
@@ -579,14 +584,14 @@ class StylesBuilder:
|
||||
color: Color | None = None
|
||||
alpha: float | None = None
|
||||
|
||||
self.styles._rules[f"auto_{name}"] = False
|
||||
self.styles._rules[f"auto_{name}"] = False # type: ignore
|
||||
for token in tokens:
|
||||
if (
|
||||
"background" not in name
|
||||
and token.name == "token"
|
||||
and token.value == "auto"
|
||||
):
|
||||
self.styles._rules[f"auto_{name}"] = True
|
||||
self.styles._rules[f"auto_{name}"] = True # type: ignore
|
||||
elif token.name == "scalar":
|
||||
alpha_scalar = Scalar.parse(token.value)
|
||||
if alpha_scalar.unit != Unit.PERCENT:
|
||||
@@ -608,7 +613,7 @@ class StylesBuilder:
|
||||
if color is not None or alpha is not None:
|
||||
if alpha is not None:
|
||||
color = (color or Color(255, 255, 255)).with_alpha(alpha)
|
||||
self.styles._rules[name] = color
|
||||
self.styles._rules[name] = color # type: ignore
|
||||
|
||||
process_tint = process_color
|
||||
process_background = process_color
|
||||
@@ -636,7 +641,7 @@ class StylesBuilder:
|
||||
)
|
||||
|
||||
style_definition = " ".join(token.value for token in tokens)
|
||||
self.styles._rules[name.replace("-", "_")] = style_definition
|
||||
self.styles._rules[name.replace("-", "_")] = style_definition # type: ignore
|
||||
|
||||
process_link_style = process_text_style
|
||||
process_link_hover_style = process_text_style
|
||||
@@ -653,7 +658,7 @@ class StylesBuilder:
|
||||
text_align_help_text(),
|
||||
)
|
||||
|
||||
self.styles._rules["text_align"] = tokens[0].value
|
||||
self.styles._rules["text_align"] = tokens[0].value # type: ignore
|
||||
|
||||
def process_dock(self, name: str, tokens: list[Token]) -> None:
|
||||
if not tokens:
|
||||
@@ -766,8 +771,8 @@ class StylesBuilder:
|
||||
align_error(name, token_horizontal)
|
||||
|
||||
name = name.replace("-", "_")
|
||||
self.styles._rules[f"{name}_horizontal"] = token_horizontal.value
|
||||
self.styles._rules[f"{name}_vertical"] = token_vertical.value
|
||||
self.styles._rules[f"{name}_horizontal"] = token_horizontal.value # type: ignore
|
||||
self.styles._rules[f"{name}_vertical"] = token_vertical.value # type: ignore
|
||||
|
||||
def process_align_horizontal(self, name: str, tokens: list[Token]) -> None:
|
||||
try:
|
||||
@@ -779,7 +784,7 @@ class StylesBuilder:
|
||||
string_enum_help_text(name, VALID_ALIGN_HORIZONTAL, context="css"),
|
||||
)
|
||||
else:
|
||||
self.styles._rules[name.replace("-", "_")] = value
|
||||
self.styles._rules[name.replace("-", "_")] = value # type: ignore
|
||||
|
||||
def process_align_vertical(self, name: str, tokens: list[Token]) -> None:
|
||||
try:
|
||||
@@ -791,7 +796,7 @@ class StylesBuilder:
|
||||
string_enum_help_text(name, VALID_ALIGN_VERTICAL, context="css"),
|
||||
)
|
||||
else:
|
||||
self.styles._rules[name.replace("-", "_")] = value
|
||||
self.styles._rules[name.replace("-", "_")] = value # type: ignore
|
||||
|
||||
process_content_align = process_align
|
||||
process_content_align_horizontal = process_align_horizontal
|
||||
@@ -807,7 +812,7 @@ class StylesBuilder:
|
||||
string_enum_help_text(name, VALID_SCROLLBAR_GUTTER, context="css"),
|
||||
)
|
||||
else:
|
||||
self.styles._rules[name.replace("-", "_")] = value
|
||||
self.styles._rules[name.replace("-", "_")] = value # type: ignore
|
||||
|
||||
def process_scrollbar_size(self, name: str, tokens: list[Token]) -> None:
|
||||
def scrollbar_size_error(name: str, token: Token) -> None:
|
||||
@@ -876,7 +881,7 @@ class StylesBuilder:
|
||||
token,
|
||||
table_rows_or_columns_help_text(name, token.value, context="css"),
|
||||
)
|
||||
self.styles._rules[name.replace("-", "_")] = scalars
|
||||
self.styles._rules[name.replace("-", "_")] = scalars # type: ignore
|
||||
|
||||
process_grid_rows = _process_grid_rows_or_columns
|
||||
process_grid_columns = _process_grid_rows_or_columns
|
||||
@@ -893,7 +898,7 @@ class StylesBuilder:
|
||||
value = int(token.value)
|
||||
if value == 0:
|
||||
self.error(name, token, integer_help_text(name))
|
||||
self.styles._rules[name.replace("-", "_")] = value
|
||||
self.styles._rules[name.replace("-", "_")] = value # type: ignore
|
||||
|
||||
process_grid_gutter_horizontal = _process_integer
|
||||
process_grid_gutter_vertical = _process_integer
|
||||
|
||||
@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Iterable
|
||||
|
||||
import rich.repr
|
||||
|
||||
from ._help_renderables import HelpText
|
||||
from .styles import Styles
|
||||
from .tokenize import Token
|
||||
from .types import Specificity3
|
||||
@@ -155,7 +156,7 @@ class SelectorSet:
|
||||
class RuleSet:
|
||||
selector_set: list[SelectorSet] = field(default_factory=list)
|
||||
styles: Styles = field(default_factory=Styles)
|
||||
errors: list[tuple[Token, str]] = field(default_factory=list)
|
||||
errors: list[tuple[Token, str | HelpText]] = field(default_factory=list)
|
||||
|
||||
is_default_rules: bool = False
|
||||
tie_breaker: int = 0
|
||||
|
||||
@@ -5,6 +5,7 @@ from pathlib import PurePath
|
||||
from typing import Iterable, Iterator, NoReturn
|
||||
|
||||
from ..suggestions import get_suggestion
|
||||
from ._help_renderables import HelpText
|
||||
from ._styles_builder import DeclarationError, StylesBuilder
|
||||
from .errors import UnresolvedVariableError
|
||||
from .model import (
|
||||
@@ -130,7 +131,7 @@ def parse_rule_set(
|
||||
|
||||
declaration = Declaration(token, "")
|
||||
|
||||
errors: list[tuple[Token, str]] = []
|
||||
errors: list[tuple[Token, str | HelpText]] = []
|
||||
|
||||
while True:
|
||||
token = next(tokens)
|
||||
|
||||
@@ -367,8 +367,8 @@ class StylesBase(ABC):
|
||||
def auto_dimensions(self) -> bool:
|
||||
"""Check if width or height are set to 'auto'."""
|
||||
has_rule = self.has_rule
|
||||
return (has_rule("width") and self.width.is_auto) or (
|
||||
has_rule("height") and self.height.is_auto
|
||||
return (has_rule("width") and self.width.is_auto) or ( # type: ignore
|
||||
has_rule("height") and self.height.is_auto # type: ignore
|
||||
)
|
||||
|
||||
@abstractmethod
|
||||
@@ -603,7 +603,7 @@ class Styles(StylesBase):
|
||||
Returns:
|
||||
``True`` if a rule was cleared, or ``False`` if it was already not set.
|
||||
"""
|
||||
changed = self._rules.pop(rule, None) is not None
|
||||
changed = self._rules.pop(rule, None) is not None # type: ignore
|
||||
if changed:
|
||||
self._updates += 1
|
||||
return changed
|
||||
@@ -622,12 +622,12 @@ class Styles(StylesBase):
|
||||
``True`` if the rule changed, otherwise ``False``.
|
||||
"""
|
||||
if value is None:
|
||||
changed = self._rules.pop(rule, None) is not None
|
||||
changed = self._rules.pop(rule, None) is not None # type: ignore
|
||||
if changed:
|
||||
self._updates += 1
|
||||
return changed
|
||||
current = self._rules.get(rule)
|
||||
self._rules[rule] = value
|
||||
self._rules[rule] = value # type: ignore
|
||||
changed = current != value
|
||||
if changed:
|
||||
self._updates += 1
|
||||
@@ -646,7 +646,7 @@ class Styles(StylesBase):
|
||||
def reset(self) -> None:
|
||||
"""Reset the rules to initial state."""
|
||||
self._updates += 1
|
||||
self._rules.clear()
|
||||
self._rules.clear() # type: ignore
|
||||
|
||||
def merge(self, other: Styles) -> None:
|
||||
"""Merge values from another Styles.
|
||||
@@ -736,25 +736,25 @@ class Styles(StylesBase):
|
||||
left = get_rule(f"{name}_left")
|
||||
|
||||
if top == right and right == bottom and bottom == left:
|
||||
border_type, border_color = rules[f"{name}_top"]
|
||||
border_type, border_color = rules[f"{name}_top"] # type: ignore
|
||||
yield name, f"{border_type} {border_color.hex}"
|
||||
return
|
||||
|
||||
# Check for edges
|
||||
if has_top:
|
||||
border_type, border_color = rules[f"{name}_top"]
|
||||
border_type, border_color = rules[f"{name}_top"] # type: ignore
|
||||
yield f"{name}-top", f"{border_type} {border_color.hex}"
|
||||
|
||||
if has_right:
|
||||
border_type, border_color = rules[f"{name}_right"]
|
||||
border_type, border_color = rules[f"{name}_right"] # type: ignore
|
||||
yield f"{name}-right", f"{border_type} {border_color.hex}"
|
||||
|
||||
if has_bottom:
|
||||
border_type, border_color = rules[f"{name}_bottom"]
|
||||
border_type, border_color = rules[f"{name}_bottom"] # type: ignore
|
||||
yield f"{name}-bottom", f"{border_type} {border_color.hex}"
|
||||
|
||||
if has_left:
|
||||
border_type, border_color = rules[f"{name}_left"]
|
||||
border_type, border_color = rules[f"{name}_left"] # type: ignore
|
||||
yield f"{name}-left", f"{border_type} {border_color.hex}"
|
||||
|
||||
@property
|
||||
@@ -770,15 +770,14 @@ class Styles(StylesBase):
|
||||
|
||||
rules = self.get_rules()
|
||||
get_rule = rules.get
|
||||
has_rule = rules.__contains__
|
||||
|
||||
if has_rule("display"):
|
||||
if "display" in rules:
|
||||
append_declaration("display", rules["display"])
|
||||
if has_rule("visibility"):
|
||||
if "visibility" in rules:
|
||||
append_declaration("visibility", rules["visibility"])
|
||||
if has_rule("padding"):
|
||||
if "padding" in rules:
|
||||
append_declaration("padding", rules["padding"].css)
|
||||
if has_rule("margin"):
|
||||
if "margin" in rules:
|
||||
append_declaration("margin", rules["margin"].css)
|
||||
|
||||
for name, rule in self._get_border_css_lines(rules, "border"):
|
||||
@@ -787,90 +786,90 @@ class Styles(StylesBase):
|
||||
for name, rule in self._get_border_css_lines(rules, "outline"):
|
||||
append_declaration(name, rule)
|
||||
|
||||
if has_rule("offset"):
|
||||
if "offset" in rules:
|
||||
x, y = self.offset
|
||||
append_declaration("offset", f"{x} {y}")
|
||||
if has_rule("dock"):
|
||||
if "dock" in rules:
|
||||
append_declaration("dock", rules["dock"])
|
||||
if has_rule("layers"):
|
||||
if "layers" in rules:
|
||||
append_declaration("layers", " ".join(self.layers))
|
||||
if has_rule("layer"):
|
||||
if "layer" in rules:
|
||||
append_declaration("layer", self.layer)
|
||||
if has_rule("layout"):
|
||||
if "layout" in rules:
|
||||
assert self.layout is not None
|
||||
append_declaration("layout", self.layout.name)
|
||||
|
||||
if has_rule("color"):
|
||||
if "color" in rules:
|
||||
append_declaration("color", self.color.hex)
|
||||
if has_rule("background"):
|
||||
if "background" in rules:
|
||||
append_declaration("background", self.background.hex)
|
||||
if has_rule("text_style"):
|
||||
if "text_style" in rules:
|
||||
append_declaration("text-style", str(get_rule("text_style")))
|
||||
if has_rule("tint"):
|
||||
if "tint" in rules:
|
||||
append_declaration("tint", self.tint.css)
|
||||
|
||||
if has_rule("overflow_x"):
|
||||
if "overflow_x" in rules:
|
||||
append_declaration("overflow-x", self.overflow_x)
|
||||
if has_rule("overflow_y"):
|
||||
if "overflow_y" in rules:
|
||||
append_declaration("overflow-y", self.overflow_y)
|
||||
|
||||
if has_rule("scrollbar_color"):
|
||||
if "scrollbar_color" in rules:
|
||||
append_declaration("scrollbar-color", self.scrollbar_color.css)
|
||||
if has_rule("scrollbar_color_hover"):
|
||||
if "scrollbar_color_hover" in rules:
|
||||
append_declaration("scrollbar-color-hover", self.scrollbar_color_hover.css)
|
||||
if has_rule("scrollbar_color_active"):
|
||||
if "scrollbar_color_active" in rules:
|
||||
append_declaration(
|
||||
"scrollbar-color-active", self.scrollbar_color_active.css
|
||||
)
|
||||
|
||||
if has_rule("scrollbar_corner_color"):
|
||||
if "scrollbar_corner_color" in rules:
|
||||
append_declaration(
|
||||
"scrollbar-corner-color", self.scrollbar_corner_color.css
|
||||
)
|
||||
|
||||
if has_rule("scrollbar_background"):
|
||||
if "scrollbar_background" in rules:
|
||||
append_declaration("scrollbar-background", self.scrollbar_background.css)
|
||||
if has_rule("scrollbar_background_hover"):
|
||||
if "scrollbar_background_hover" in rules:
|
||||
append_declaration(
|
||||
"scrollbar-background-hover", self.scrollbar_background_hover.css
|
||||
)
|
||||
if has_rule("scrollbar_background_active"):
|
||||
if "scrollbar_background_active" in rules:
|
||||
append_declaration(
|
||||
"scrollbar-background-active", self.scrollbar_background_active.css
|
||||
)
|
||||
|
||||
if has_rule("scrollbar_gutter"):
|
||||
if "scrollbar_gutter" in rules:
|
||||
append_declaration("scrollbar-gutter", self.scrollbar_gutter)
|
||||
if has_rule("scrollbar_size"):
|
||||
if "scrollbar_size" in rules:
|
||||
append_declaration(
|
||||
"scrollbar-size",
|
||||
f"{self.scrollbar_size_horizontal} {self.scrollbar_size_vertical}",
|
||||
)
|
||||
else:
|
||||
if has_rule("scrollbar_size_horizontal"):
|
||||
if "scrollbar_size_horizontal" in rules:
|
||||
append_declaration(
|
||||
"scrollbar-size-horizontal", str(self.scrollbar_size_horizontal)
|
||||
)
|
||||
if has_rule("scrollbar_size_vertical"):
|
||||
if "scrollbar_size_vertical" in rules:
|
||||
append_declaration(
|
||||
"scrollbar-size-vertical", str(self.scrollbar_size_vertical)
|
||||
)
|
||||
|
||||
if has_rule("box_sizing"):
|
||||
if "box_sizing" in rules:
|
||||
append_declaration("box-sizing", self.box_sizing)
|
||||
if has_rule("width"):
|
||||
if "width" in rules:
|
||||
append_declaration("width", str(self.width))
|
||||
if has_rule("height"):
|
||||
if "height" in rules:
|
||||
append_declaration("height", str(self.height))
|
||||
if has_rule("min_width"):
|
||||
if "min_width" in rules:
|
||||
append_declaration("min-width", str(self.min_width))
|
||||
if has_rule("min_height"):
|
||||
if "min_height" in rules:
|
||||
append_declaration("min-height", str(self.min_height))
|
||||
if has_rule("max_width"):
|
||||
if "max_width" in rules:
|
||||
append_declaration("max-width", str(self.min_width))
|
||||
if has_rule("max_height"):
|
||||
if "max_height" in rules:
|
||||
append_declaration("max-height", str(self.min_height))
|
||||
if has_rule("transitions"):
|
||||
if "transitions" in rules:
|
||||
append_declaration(
|
||||
"transition",
|
||||
", ".join(
|
||||
@@ -879,74 +878,74 @@ class Styles(StylesBase):
|
||||
),
|
||||
)
|
||||
|
||||
if has_rule("align_horizontal") and has_rule("align_vertical"):
|
||||
if "align_horizontal" in rules and "align_vertical" in rules:
|
||||
append_declaration(
|
||||
"align", f"{self.align_horizontal} {self.align_vertical}"
|
||||
)
|
||||
elif has_rule("align_horizontal"):
|
||||
elif "align_horizontal" in rules:
|
||||
append_declaration("align-horizontal", self.align_horizontal)
|
||||
elif has_rule("align_vertical"):
|
||||
elif "align_vertical" in rules:
|
||||
append_declaration("align-vertical", self.align_vertical)
|
||||
|
||||
if has_rule("content_align_horizontal") and has_rule("content_align_vertical"):
|
||||
if "content_align_horizontal" in rules and "content_align_vertical" in rules:
|
||||
append_declaration(
|
||||
"content-align",
|
||||
f"{self.content_align_horizontal} {self.content_align_vertical}",
|
||||
)
|
||||
elif has_rule("content_align_horizontal"):
|
||||
elif "content_align_horizontal" in rules:
|
||||
append_declaration(
|
||||
"content-align-horizontal", self.content_align_horizontal
|
||||
)
|
||||
elif has_rule("content_align_vertical"):
|
||||
elif "content_align_vertical" in rules:
|
||||
append_declaration("content-align-vertical", self.content_align_vertical)
|
||||
|
||||
if has_rule("text_align"):
|
||||
if "text_align" in rules:
|
||||
append_declaration("text-align", self.text_align)
|
||||
|
||||
if has_rule("opacity"):
|
||||
if "opacity" in rules:
|
||||
append_declaration("opacity", str(self.opacity))
|
||||
if has_rule("text_opacity"):
|
||||
if "text_opacity" in rules:
|
||||
append_declaration("text-opacity", str(self.text_opacity))
|
||||
|
||||
if has_rule("grid_columns"):
|
||||
if "grid_columns" in rules:
|
||||
append_declaration(
|
||||
"grid-columns",
|
||||
" ".join(str(scalar) for scalar in self.grid_columns or ()),
|
||||
)
|
||||
if has_rule("grid_rows"):
|
||||
if "grid_rows" in rules:
|
||||
append_declaration(
|
||||
"grid-rows",
|
||||
" ".join(str(scalar) for scalar in self.grid_rows or ()),
|
||||
)
|
||||
if has_rule("grid_size_columns"):
|
||||
if "grid_size_columns" in rules:
|
||||
append_declaration("grid-size-columns", str(self.grid_size_columns))
|
||||
if has_rule("grid_size_rows"):
|
||||
if "grid_size_rows" in rules:
|
||||
append_declaration("grid-size-rows", str(self.grid_size_rows))
|
||||
|
||||
if has_rule("grid_gutter_horizontal"):
|
||||
if "grid_gutter_horizontal" in rules:
|
||||
append_declaration(
|
||||
"grid-gutter-horizontal", str(self.grid_gutter_horizontal)
|
||||
)
|
||||
if has_rule("grid_gutter_vertical"):
|
||||
if "grid_gutter_vertical" in rules:
|
||||
append_declaration("grid-gutter-vertical", str(self.grid_gutter_vertical))
|
||||
|
||||
if has_rule("row_span"):
|
||||
if "row_span" in rules:
|
||||
append_declaration("row-span", str(self.row_span))
|
||||
if has_rule("column_span"):
|
||||
if "column_span" in rules:
|
||||
append_declaration("column-span", str(self.column_span))
|
||||
|
||||
if has_rule("link_color"):
|
||||
if "link_color" in rules:
|
||||
append_declaration("link-color", self.link_color.css)
|
||||
if has_rule("link_background"):
|
||||
if "link_background" in rules:
|
||||
append_declaration("link-background", self.link_background.css)
|
||||
if has_rule("link_style"):
|
||||
if "link_style" in rules:
|
||||
append_declaration("link-style", str(self.link_style))
|
||||
|
||||
if has_rule("link_hover_color"):
|
||||
if "link_hover_color" in rules:
|
||||
append_declaration("link-hover-color", self.link_hover_color.css)
|
||||
if has_rule("link_hover_background"):
|
||||
if "link_hover_background" in rules:
|
||||
append_declaration("link-hover-background", self.link_hover_background.css)
|
||||
if has_rule("link_hover_style"):
|
||||
if "link_hover_style" in rules:
|
||||
append_declaration("link-hover-style", str(self.link_hover_style))
|
||||
|
||||
lines.sort()
|
||||
|
||||
@@ -4,7 +4,7 @@ import os
|
||||
from collections import defaultdict
|
||||
from operator import itemgetter
|
||||
from pathlib import Path, PurePath
|
||||
from typing import Iterable, NamedTuple, cast
|
||||
from typing import Iterable, NamedTuple, Sequence, cast
|
||||
|
||||
import rich.repr
|
||||
from rich.console import Console, ConsoleOptions, RenderableType, RenderResult
|
||||
@@ -248,7 +248,7 @@ class Stylesheet:
|
||||
self.source[str(path)] = CssSource(css, False, 0)
|
||||
self._require_parse = True
|
||||
|
||||
def read_all(self, paths: list[PurePath]) -> None:
|
||||
def read_all(self, paths: Sequence[PurePath]) -> None:
|
||||
"""Read multiple CSS files, in order.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -132,10 +132,12 @@ class DOMNode(MessagePump):
|
||||
check_identifiers("class name", *_classes)
|
||||
self._classes.update(_classes)
|
||||
|
||||
self.children = NodeList()
|
||||
self.children: NodeList = NodeList()
|
||||
self._css_styles: Styles = Styles(self)
|
||||
self._inline_styles: Styles = Styles(self)
|
||||
self.styles = RenderStyles(self, self._css_styles, self._inline_styles)
|
||||
self.styles: RenderStyles = RenderStyles(
|
||||
self, self._css_styles, self._inline_styles
|
||||
)
|
||||
# A mapping of class names to Styles set in COMPONENT_CLASSES
|
||||
self._component_styles: dict[str, RenderStyles] = {}
|
||||
|
||||
|
||||
@@ -7,12 +7,12 @@ from ctypes import Structure, Union, byref, wintypes
|
||||
from ctypes.wintypes import BOOL, CHAR, DWORD, HANDLE, SHORT, UINT, WCHAR, WORD
|
||||
from typing import IO, Callable, List, Optional
|
||||
|
||||
from .._types import EventTarget
|
||||
from .._types import MessageTarget
|
||||
from .._xterm_parser import XTermParser
|
||||
from ..events import Event, Resize
|
||||
from ..geometry import Size
|
||||
|
||||
KERNEL32 = ctypes.WinDLL("kernel32", use_last_error=True)
|
||||
KERNEL32 = ctypes.WinDLL("kernel32", use_last_error=True) # type: ignore
|
||||
|
||||
# Console input modes
|
||||
ENABLE_ECHO_INPUT = 0x0004
|
||||
@@ -130,7 +130,7 @@ def _set_console_mode(file: IO, mode: int) -> bool:
|
||||
Returns:
|
||||
True on success, otherwise False.
|
||||
"""
|
||||
windows_filehandle = msvcrt.get_osfhandle(file.fileno())
|
||||
windows_filehandle = msvcrt.get_osfhandle(file.fileno()) # type: ignore
|
||||
success = KERNEL32.SetConsoleMode(windows_filehandle, mode)
|
||||
return success
|
||||
|
||||
@@ -144,7 +144,7 @@ def _get_console_mode(file: IO) -> int:
|
||||
Returns:
|
||||
The current console mode.
|
||||
"""
|
||||
windows_filehandle = msvcrt.get_osfhandle(file.fileno())
|
||||
windows_filehandle = msvcrt.get_osfhandle(file.fileno()) # type: ignore
|
||||
mode = wintypes.DWORD()
|
||||
KERNEL32.GetConsoleMode(windows_filehandle, ctypes.byref(mode))
|
||||
return mode.value
|
||||
@@ -211,7 +211,7 @@ class EventMonitor(threading.Thread):
|
||||
self,
|
||||
loop: AbstractEventLoop,
|
||||
app,
|
||||
target: EventTarget,
|
||||
target: MessageTarget,
|
||||
exit_event: threading.Event,
|
||||
process_event: Callable[[Event], None],
|
||||
) -> None:
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import PurePath
|
||||
from typing import Callable
|
||||
from typing import Callable, Sequence
|
||||
|
||||
import rich.repr
|
||||
|
||||
@@ -13,7 +13,7 @@ from ._callback import invoke
|
||||
class FileMonitor:
|
||||
"""Monitors files for changes and invokes a callback when it does."""
|
||||
|
||||
def __init__(self, paths: list[PurePath], callback: Callable) -> None:
|
||||
def __init__(self, paths: Sequence[PurePath], callback: Callable) -> None:
|
||||
self.paths = paths
|
||||
self.callback = callback
|
||||
self._modified = self._get_last_modified_time()
|
||||
|
||||
@@ -30,14 +30,14 @@ class ScrollView(Widget):
|
||||
"""Not transparent, i.e. renders something."""
|
||||
return False
|
||||
|
||||
def watch_scroll_x(self, new_value: float) -> None:
|
||||
if self.show_horizontal_scrollbar:
|
||||
self.horizontal_scrollbar.position = int(new_value)
|
||||
def watch_scroll_x(self, old_value: float, new_value: float) -> None:
|
||||
if self.show_horizontal_scrollbar and round(old_value) != round(new_value):
|
||||
self.horizontal_scrollbar.position = round(new_value)
|
||||
self.refresh()
|
||||
|
||||
def watch_scroll_y(self, new_value: float) -> None:
|
||||
if self.show_vertical_scrollbar:
|
||||
self.vertical_scrollbar.position = int(new_value)
|
||||
def watch_scroll_y(self, old_value: float, new_value: float) -> None:
|
||||
if self.show_vertical_scrollbar and round(old_value) != round(new_value):
|
||||
self.vertical_scrollbar.position = round(new_value)
|
||||
self.refresh()
|
||||
|
||||
def on_mount(self):
|
||||
|
||||
@@ -117,7 +117,7 @@ class _Styled:
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, renderable: "RenderableType", style: Style, link_style: Style | None
|
||||
self, renderable: "ConsoleRenderable", style: Style, link_style: Style | None
|
||||
) -> None:
|
||||
self.renderable = renderable
|
||||
self.style = style
|
||||
@@ -133,7 +133,7 @@ class _Styled:
|
||||
if style:
|
||||
apply = style.__add__
|
||||
result_segments = (
|
||||
_Segment(text, apply(_style), control)
|
||||
_Segment(text, apply(_style), None)
|
||||
for text, _style, control in result_segments
|
||||
)
|
||||
link_style = self.link_style
|
||||
@@ -141,19 +141,22 @@ class _Styled:
|
||||
result_segments = (
|
||||
_Segment(
|
||||
text,
|
||||
(
|
||||
style
|
||||
if style._meta is None
|
||||
else (style + link_style if "@click" in style.meta else style),
|
||||
else (style + link_style if "@click" in style.meta else style)
|
||||
),
|
||||
control,
|
||||
)
|
||||
for text, style, control in result_segments
|
||||
if style is not None
|
||||
)
|
||||
return result_segments
|
||||
|
||||
def __rich_measure__(
|
||||
self, console: "Console", options: "ConsoleOptions"
|
||||
) -> Measurement:
|
||||
return self.renderable.__rich_measure__(console, options)
|
||||
return Measurement.get(console, options, self.renderable)
|
||||
|
||||
|
||||
class RenderCache(NamedTuple):
|
||||
@@ -1414,6 +1417,7 @@ class Widget(DOMNode):
|
||||
easing = DEFAULT_SCROLL_EASING
|
||||
|
||||
if maybe_scroll_x:
|
||||
assert x is not None
|
||||
self.scroll_target_x = x
|
||||
if x != self.scroll_x:
|
||||
self.animate(
|
||||
@@ -1425,6 +1429,7 @@ class Widget(DOMNode):
|
||||
)
|
||||
scrolled_x = True
|
||||
if maybe_scroll_y:
|
||||
assert y is not None
|
||||
self.scroll_target_y = y
|
||||
if y != self.scroll_y:
|
||||
self.animate(
|
||||
@@ -1438,10 +1443,12 @@ class Widget(DOMNode):
|
||||
|
||||
else:
|
||||
if maybe_scroll_x:
|
||||
assert x is not None
|
||||
scroll_x = self.scroll_x
|
||||
self.scroll_target_x = self.scroll_x = x
|
||||
scrolled_x = scroll_x != self.scroll_x
|
||||
if maybe_scroll_y:
|
||||
assert y is not None
|
||||
scroll_y = self.scroll_y
|
||||
self.scroll_target_y = self.scroll_y = y
|
||||
scrolled_y = scroll_y != self.scroll_y
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, ClassVar, Generic, NewType, TypeVar
|
||||
from typing import TYPE_CHECKING, ClassVar, Generic, Iterable, NewType, TypeVar, cast
|
||||
|
||||
import rich.repr
|
||||
from rich.style import NULL_STYLE, Style
|
||||
@@ -783,7 +783,7 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True):
|
||||
assert self._tree_lines_cached is not None
|
||||
return self._tree_lines_cached
|
||||
|
||||
def _on_idle(self) -> None:
|
||||
async def _on_idle(self, event: events.Idle) -> None:
|
||||
"""Check tree needs a rebuild on idle."""
|
||||
# Property calls build if required
|
||||
self._tree_lines
|
||||
@@ -891,6 +891,7 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True):
|
||||
Returns:
|
||||
Strings for space, vertical, terminator and cross.
|
||||
"""
|
||||
lines: tuple[Iterable[str], Iterable[str], Iterable[str], Iterable[str]]
|
||||
if self.show_guides:
|
||||
lines = self.LINES["default"]
|
||||
if style.bold:
|
||||
@@ -901,11 +902,11 @@ class Tree(Generic[TreeDataType], ScrollView, can_focus=True):
|
||||
lines = (" ", " ", " ", " ")
|
||||
|
||||
guide_depth = max(0, self.guide_depth - 2)
|
||||
lines = tuple(
|
||||
f"{vertical}{horizontal * guide_depth} "
|
||||
for vertical, horizontal in lines
|
||||
guide_lines = tuple(
|
||||
f"{characters[0]}{characters[1] * guide_depth} "
|
||||
for characters in lines
|
||||
)
|
||||
return lines
|
||||
return cast("tuple[str, str, str, str]", guide_lines)
|
||||
|
||||
if is_hover:
|
||||
line_style = self.get_component_rich_style("tree--highlight-line")
|
||||
|
||||
Reference in New Issue
Block a user