mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
tweak to log
This commit is contained in:
@@ -58,7 +58,7 @@ App > Screen {
|
|||||||
#header {
|
#header {
|
||||||
color: $text-primary-darken-1;
|
color: $text-primary-darken-1;
|
||||||
background: $primary-darken-1;
|
background: $primary-darken-1;
|
||||||
height: 3;
|
height: 3
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,9 +74,9 @@ App > Screen {
|
|||||||
Tweet {
|
Tweet {
|
||||||
height: 22;
|
height: 22;
|
||||||
max-width: 80;
|
max-width: 80;
|
||||||
margin: 1 3;
|
margin: 1 3;
|
||||||
background: $panel;
|
background: $panel;
|
||||||
color: $text-panel
|
color: $text-panel;
|
||||||
layout: vertical;
|
layout: vertical;
|
||||||
/* border: outer $primary; */
|
/* border: outer $primary; */
|
||||||
padding: 1;
|
padding: 1;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import asyncio
|
|||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
from time import perf_counter
|
||||||
import warnings
|
import warnings
|
||||||
from asyncio import AbstractEventLoop
|
from asyncio import AbstractEventLoop
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -29,7 +30,7 @@ from ._callback import invoke
|
|||||||
from ._context import active_app
|
from ._context import active_app
|
||||||
from ._event_broker import extract_handler_actions, NoHandler
|
from ._event_broker import extract_handler_actions, NoHandler
|
||||||
from .binding import Bindings, NoBinding
|
from .binding import Bindings, NoBinding
|
||||||
from .css.stylesheet import Stylesheet, StylesheetParseError, StylesheetError
|
from .css.stylesheet import Stylesheet
|
||||||
from .devtools.client import DevtoolsClient, DevtoolsConnectionError
|
from .devtools.client import DevtoolsClient, DevtoolsConnectionError
|
||||||
from .design import ColorSystem
|
from .design import ColorSystem
|
||||||
from .dom import DOMNode
|
from .dom import DOMNode
|
||||||
@@ -102,6 +103,7 @@ class App(DOMNode):
|
|||||||
"""
|
"""
|
||||||
self.console = Console(markup=False, highlight=False)
|
self.console = Console(markup=False, highlight=False)
|
||||||
self.error_console = Console(markup=False, stderr=True)
|
self.error_console = Console(markup=False, stderr=True)
|
||||||
|
|
||||||
self._screen = screen
|
self._screen = screen
|
||||||
self.driver_class = driver_class or self.get_driver_class()
|
self.driver_class = driver_class or self.get_driver_class()
|
||||||
self._title = title
|
self._title = title
|
||||||
@@ -121,7 +123,16 @@ class App(DOMNode):
|
|||||||
self.bindings = Bindings()
|
self.bindings = Bindings()
|
||||||
self._title = title
|
self._title = title
|
||||||
|
|
||||||
self.log_file = open(log, "wt") if log else None
|
self._log_console: Console | None = None
|
||||||
|
if log:
|
||||||
|
self.log_file = open(log, "wt")
|
||||||
|
self._log_console = Console(
|
||||||
|
file=self.log_file, markup=False, emoji=False, highlight=False
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self._log_console = None
|
||||||
|
self._log_file = None
|
||||||
|
|
||||||
self.log_verbosity = log_verbosity
|
self.log_verbosity = log_verbosity
|
||||||
|
|
||||||
self.bindings.bind("ctrl+c", "quit", show=False, allow_forward=False)
|
self.bindings.bind("ctrl+c", "quit", show=False, allow_forward=False)
|
||||||
@@ -219,30 +230,36 @@ class App(DOMNode):
|
|||||||
_textual_calling_frame (inspect.FrameInfo | None): The frame info to include in
|
_textual_calling_frame (inspect.FrameInfo | None): The frame info to include in
|
||||||
the log message sent to the devtools server.
|
the log message sent to the devtools server.
|
||||||
"""
|
"""
|
||||||
output = ""
|
if verbosity > self.log_verbosity:
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
output = f" ".join(str(arg) for arg in objects)
|
if len(objects) == 1:
|
||||||
if kwargs:
|
if self._log_console is not None:
|
||||||
key_values = " ".join(f"{key}={value}" for key, value in kwargs.items())
|
self._log_console.print(objects[0])
|
||||||
output = " ".join((output, key_values))
|
if self.devtools.is_connected:
|
||||||
|
if not _textual_calling_frame:
|
||||||
if not _textual_calling_frame:
|
_textual_calling_frame = inspect.stack()[1]
|
||||||
_textual_calling_frame = inspect.stack()[1]
|
calling_path = _textual_calling_frame.filename
|
||||||
|
calling_lineno = _textual_calling_frame.lineno
|
||||||
calling_path = _textual_calling_frame.filename
|
|
||||||
calling_lineno = _textual_calling_frame.lineno
|
|
||||||
|
|
||||||
if self.devtools.is_connected and verbosity <= self.log_verbosity:
|
|
||||||
if len(objects) > 1 or len(kwargs) >= 1 and output:
|
|
||||||
self.devtools.log(output, path=calling_path, lineno=calling_lineno)
|
|
||||||
else:
|
|
||||||
self.devtools.log(
|
self.devtools.log(
|
||||||
*objects, path=calling_path, lineno=calling_lineno
|
objects[0], path=calling_path, lineno=calling_lineno
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
if self.log_file and verbosity <= self.log_verbosity:
|
output = f" ".join(str(arg) for arg in objects)
|
||||||
self.log_file.write(output + "\n")
|
if kwargs:
|
||||||
self.log_file.flush()
|
key_values = " ".join(
|
||||||
|
f"{key}={value}" for key, value in kwargs.items()
|
||||||
|
)
|
||||||
|
output = " ".join((output, key_values))
|
||||||
|
if self._log_console is not None:
|
||||||
|
self._log_console.print(output, soft_wrap=True)
|
||||||
|
if self.devtools.is_connected:
|
||||||
|
if not _textual_calling_frame:
|
||||||
|
_textual_calling_frame = inspect.stack()[1]
|
||||||
|
calling_path = _textual_calling_frame.filename
|
||||||
|
calling_lineno = _textual_calling_frame.lineno
|
||||||
|
self.devtools.log(output, path=calling_path, lineno=calling_lineno)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -310,11 +327,13 @@ class App(DOMNode):
|
|||||||
if self.css_file is not None:
|
if self.css_file is not None:
|
||||||
stylesheet = Stylesheet(variables=self.get_css_variables())
|
stylesheet = Stylesheet(variables=self.get_css_variables())
|
||||||
try:
|
try:
|
||||||
self.log("loading", self.css_file)
|
time = perf_counter()
|
||||||
stylesheet.read(self.css_file)
|
stylesheet.read(self.css_file)
|
||||||
except StylesheetError as error:
|
elapsed = (perf_counter() - time) * 1000
|
||||||
self.log(error)
|
self.log(f"loaded {self.css_file} in {elapsed:.0f}ms")
|
||||||
|
except Exception as error:
|
||||||
self.console.bell()
|
self.console.bell()
|
||||||
|
self.log(error)
|
||||||
else:
|
else:
|
||||||
self.reset_styles()
|
self.reset_styles()
|
||||||
self.stylesheet = stylesheet
|
self.stylesheet = stylesheet
|
||||||
|
|||||||
@@ -275,8 +275,8 @@ class StylesBuilder:
|
|||||||
space: list[int] = []
|
space: list[int] = []
|
||||||
append = space.append
|
append = space.append
|
||||||
for token in tokens:
|
for token in tokens:
|
||||||
token_name, value, _, _, location, _ = token
|
token_name, value, _, _, _, _ = token
|
||||||
if token_name in ("number", "scalar"):
|
if token_name == "number":
|
||||||
try:
|
try:
|
||||||
append(int(value))
|
append(int(value))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@@ -289,12 +289,44 @@ class StylesBuilder:
|
|||||||
)
|
)
|
||||||
self.styles._rules[name] = Spacing.unpack(cast(SpacingDimensions, tuple(space)))
|
self.styles._rules[name] = Spacing.unpack(cast(SpacingDimensions, tuple(space)))
|
||||||
|
|
||||||
|
def _process_space_partial(self, name: str, tokens: list[Token]) -> None:
|
||||||
|
if len(tokens) != 1:
|
||||||
|
self.error(name, tokens[0], "expected a single token here")
|
||||||
|
|
||||||
|
_EDGE_SPACING_MAP = {"top": 0, "right": 1, "bottom": 2, "left": 3}
|
||||||
|
token = tokens[0]
|
||||||
|
token_name, value, _, _, _, _ = token
|
||||||
|
if token_name == "number":
|
||||||
|
space = int(value)
|
||||||
|
else:
|
||||||
|
self.error(name, token, f"expected a number here; found {value!r}")
|
||||||
|
style_name, _, edge = name.replace("-", "_").partition("_")
|
||||||
|
|
||||||
|
current_spacing = cast(
|
||||||
|
tuple[int, int, int, int], self.styles._rules.get(style_name, (0, 0, 0, 0))
|
||||||
|
)
|
||||||
|
|
||||||
|
spacing_list = list(current_spacing)
|
||||||
|
spacing_list[_EDGE_SPACING_MAP[edge]] = space
|
||||||
|
|
||||||
|
self.styles._rules[style_name] = Spacing(*spacing_list)
|
||||||
|
|
||||||
def process_padding(self, name: str, tokens: list[Token]) -> None:
|
def process_padding(self, name: str, tokens: list[Token]) -> None:
|
||||||
self._process_space(name, tokens)
|
self._process_space(name, tokens)
|
||||||
|
|
||||||
def process_margin(self, name: str, tokens: list[Token]) -> None:
|
def process_margin(self, name: str, tokens: list[Token]) -> None:
|
||||||
self._process_space(name, tokens)
|
self._process_space(name, tokens)
|
||||||
|
|
||||||
|
process_margin_top = _process_space_partial
|
||||||
|
process_margin_right = _process_space_partial
|
||||||
|
process_margin_bottom = _process_space_partial
|
||||||
|
process_margin_left = _process_space_partial
|
||||||
|
|
||||||
|
process_padding_top = _process_space_partial
|
||||||
|
process_padding_right = _process_space_partial
|
||||||
|
process_padding_bottom = _process_space_partial
|
||||||
|
process_padding_left = _process_space_partial
|
||||||
|
|
||||||
def _parse_border(self, name: str, tokens: list[Token]) -> tuple[str, Color]:
|
def _parse_border(self, name: str, tokens: list[Token]) -> tuple[str, Color]:
|
||||||
border_type = "solid"
|
border_type = "solid"
|
||||||
border_color = Color(0, 255, 0)
|
border_color = Color(0, 255, 0)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ from ..dom import DOMNode
|
|||||||
from .. import log
|
from .. import log
|
||||||
|
|
||||||
|
|
||||||
class StylesheetParseError(Exception):
|
class StylesheetParseError(StylesheetError):
|
||||||
def __init__(self, errors: StylesheetErrors) -> None:
|
def __init__(self, errors: StylesheetErrors) -> None:
|
||||||
self.errors = errors
|
self.errors = errors
|
||||||
|
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ class Key(InputEvent):
|
|||||||
|
|
||||||
|
|
||||||
@rich.repr.auto
|
@rich.repr.auto
|
||||||
class MouseEvent(InputEvent, bubble=True):
|
class MouseEvent(InputEvent, bubble=True, verbosity=2):
|
||||||
"""Sent in response to a mouse event"""
|
"""Sent in response to a mouse event"""
|
||||||
|
|
||||||
__slots__ = [
|
__slots__ = [
|
||||||
@@ -344,7 +344,7 @@ class MouseScrollDown(InputEvent, verbosity=3, bubble=True):
|
|||||||
self.y = y
|
self.y = y
|
||||||
|
|
||||||
|
|
||||||
class MouseScrollUp(MouseScrollDown, bubble=True):
|
class MouseScrollUp(MouseScrollDown, verbosity=3, bubble=True):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class Screen(Widget):
|
|||||||
def on_idle(self, event: events.Idle) -> None:
|
def on_idle(self, event: events.Idle) -> None:
|
||||||
# Check for any widgets marked as 'dirty' (needs a repaint)
|
# Check for any widgets marked as 'dirty' (needs a repaint)
|
||||||
if self._dirty_widgets:
|
if self._dirty_widgets:
|
||||||
self.log(dirty=len(self._dirty_widgets))
|
# self.log(dirty=len(self._dirty_widgets))
|
||||||
for widget in self._dirty_widgets:
|
for widget in self._dirty_widgets:
|
||||||
# Repaint widgets
|
# Repaint widgets
|
||||||
# TODO: Combine these in to a single update.
|
# TODO: Combine these in to a single update.
|
||||||
|
|||||||
Reference in New Issue
Block a user