Skip to content

Commit

Permalink
move expensive imports out of module scope
Browse files Browse the repository at this point in the history
  • Loading branch information
willmcgugan committed Nov 27, 2023
1 parent d8b0583 commit 02d3b98
Show file tree
Hide file tree
Showing 14 changed files with 48 additions and 47 deletions.
4 changes: 2 additions & 2 deletions docs/examples/guide/command_palette/command01.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
from functools import partial
from pathlib import Path

from rich.syntax import Syntax

from textual.app import App, ComposeResult
from textual.command import Hit, Hits, Provider
from textual.containers import VerticalScroll
Expand Down Expand Up @@ -53,6 +51,8 @@ def compose(self) -> ComposeResult:

def open_file(self, path: Path) -> None:
"""Open and display a file with syntax highlighting."""
from rich.syntax import Syntax

syntax = Syntax.from_path(
str(path),
line_numbers=True,
Expand Down
21 changes: 0 additions & 21 deletions src/textual/_asyncio.py

This file was deleted.

19 changes: 12 additions & 7 deletions src/textual/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import platform
import sys
import threading
import unicodedata
import warnings
from asyncio import Task
from concurrent.futures import Future
Expand Down Expand Up @@ -56,12 +55,10 @@
from rich.control import Control
from rich.protocol import is_renderable
from rich.segment import Segment, Segments
from rich.traceback import Traceback

from . import Logger, LogGroup, LogVerbosity, actions, constants, events, log, messages
from ._animator import DEFAULT_EASING, Animatable, Animator, EasingFunction
from ._ansi_sequences import SYNC_END, SYNC_START
from ._asyncio import create_task
from ._callback import invoke
from ._compose import compose
from ._compositor import CompositorUpdate
Expand All @@ -84,7 +81,6 @@
from .drivers.headless_driver import HeadlessDriver
from .features import FeatureFlag, parse_features
from .file_monitor import FileMonitor
from .filter import ANSIToTruecolor, DimFilter, LineFilter, Monochrome
from .geometry import Offset, Region, Size
from .keys import (
REPLACED_KEYS,
Expand Down Expand Up @@ -114,6 +110,7 @@

# Unused & ignored imports are needed for the docs to link to these objects:
from .css.query import WrongType # type: ignore # noqa: F401
from .filter import LineFilter
from .message import Message
from .pilot import Pilot
from .widget import MountError # type: ignore # noqa: F401
Expand Down Expand Up @@ -385,11 +382,15 @@ def __init__(
environ = dict(os.environ)
no_color = environ.pop("NO_COLOR", None)
if no_color is not None:
from .filter import Monochrome

self._filters.append(Monochrome())

for filter_name in constants.FILTERS.split(","):
filter = filter_name.lower().strip()
if filter == "dim":
from .filter import ANSIToTruecolor, DimFilter

self._filters.append(ANSIToTruecolor(terminal_theme.DIMMED_MONOKAI))
self._filters.append(DimFilter())

Expand Down Expand Up @@ -1137,6 +1138,8 @@ def get_key_display(self, key: str) -> str:

async def _press_keys(self, keys: Iterable[str]) -> None:
"""A task to send key events."""
import unicodedata

app = self
driver = app._driver
assert driver is not None
Expand Down Expand Up @@ -1282,7 +1285,7 @@ async def run_app(app: App) -> None:

# Launch the app in the "background"
active_message_pump.set(app)
app_task = create_task(run_app(app), name=f"run_test {app}")
app_task = asyncio.create_task(run_app(app), name=f"run_test {app}")

# Wait until the app has performed all startup routines.
await app_ready_event.wait()
Expand Down Expand Up @@ -1353,7 +1356,7 @@ async def run_auto_pilot(

pilot = Pilot(app)
active_message_pump.set(self)
auto_pilot_task = create_task(
auto_pilot_task = asyncio.create_task(
run_auto_pilot(auto_pilot, pilot), name=repr(pilot)
)

Expand Down Expand Up @@ -2098,6 +2101,8 @@ def _handle_exception(self, error: Exception) -> None:

def _fatal_error(self) -> None:
"""Exits the app after an unhandled exception."""
from rich.traceback import Traceback

self.bell()
traceback = Traceback(
show_locals=True, width=None, locals_max_length=5, suppress=[rich]
Expand Down Expand Up @@ -2912,7 +2917,7 @@ async def prune_widgets_task(
removed_widgets = self._detach_from_dom(widgets)

finished_event = asyncio.Event()
remove_task = create_task(
remove_task = asyncio.create_task(
prune_widgets_task(removed_widgets, finished_event), name="prune nodes"
)

Expand Down
18 changes: 15 additions & 3 deletions src/textual/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@
from __future__ import annotations

from abc import ABC, abstractmethod
from asyncio import CancelledError, Queue, Task, TimeoutError, wait, wait_for
from asyncio import (
CancelledError,
Queue,
Task,
TimeoutError,
create_task,
wait,
wait_for,
)
from dataclasses import dataclass
from functools import total_ordering
from time import monotonic
Expand All @@ -19,11 +27,9 @@
from rich.emoji import Emoji
from rich.style import Style
from rich.text import Text
from rich.traceback import Traceback
from typing_extensions import Final, TypeAlias

from . import on, work
from ._asyncio import create_task
from .binding import Binding, BindingType
from .containers import Horizontal, Vertical
from .events import Click, Mount
Expand Down Expand Up @@ -165,6 +171,8 @@ async def post_init_task() -> None:
try:
await self.startup()
except Exception:
from rich.traceback import Traceback

self.app.log.error(Traceback())
else:
self._init_success = True
Expand Down Expand Up @@ -211,6 +219,8 @@ async def _shutdown(self) -> None:
try:
await self.shutdown()
except Exception:
from rich.traceback import Traceback

self.app.log.error(Traceback())

async def shutdown(self) -> None:
Expand Down Expand Up @@ -681,6 +691,8 @@ async def _search_for(self, search_value: str) -> AsyncGenerator[Hit, bool]:
if search.done():
exception = search.exception()
if exception is not None:
from rich.traceback import Traceback

self.log.error(
Traceback.from_exception(
type(exception), exception, exception.__traceback__
Expand Down
3 changes: 2 additions & 1 deletion src/textual/css/_help_renderables.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from rich.highlighter import ReprHighlighter
from rich.markup import render
from rich.text import Text
from rich.tree import Tree

_highlighter = ReprHighlighter()

Expand Down Expand Up @@ -89,6 +88,8 @@ def __str__(self) -> str:
def __rich_console__(
self, console: Console, options: ConsoleOptions
) -> RenderResult:
from rich.tree import Tree

tree = Tree(_markup_and_highlight(f"[b blue]{self.summary}"), guide_style="dim")
if self.bullets is not None:
for bullet in self.bullets:
Expand Down
3 changes: 2 additions & 1 deletion src/textual/css/errors.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

from rich.console import Console, ConsoleOptions, RenderResult
from rich.traceback import Traceback

from ._help_renderables import HelpText
from .tokenizer import Token, TokenError
Expand Down Expand Up @@ -38,6 +37,8 @@ def __init__(self, *args: object, help_text: HelpText | None = None):
def __rich_console__(
self, console: Console, options: ConsoleOptions
) -> RenderResult:
from rich.traceback import Traceback

yield Traceback.from_exception(type(self), self, self.__traceback__)
if self.help_text is not None:
yield ""
Expand Down
3 changes: 2 additions & 1 deletion src/textual/css/stylesheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from rich.markup import render
from rich.padding import Padding
from rich.panel import Panel
from rich.syntax import Syntax
from rich.text import Text

from .._cache import LRUCache
Expand Down Expand Up @@ -45,6 +44,8 @@ def __init__(self, rules: list[RuleSet]) -> None:

@classmethod
def _get_snippet(cls, code: str, line_no: int) -> RenderableType:
from rich.syntax import Syntax

syntax = Syntax(
code,
lexer="scss",
Expand Down
3 changes: 2 additions & 1 deletion src/textual/css/tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from rich.highlighter import ReprHighlighter
from rich.padding import Padding
from rich.panel import Panel
from rich.syntax import Syntax
from rich.text import Text

from ..suggestions import get_suggestion
Expand Down Expand Up @@ -51,6 +50,8 @@ def _get_snippet(self) -> Panel:
Returns:
A renderable.
"""
from rich.syntax import Syntax

line_no = self.start[0]
# TODO: Highlight column number
syntax = Syntax(
Expand Down
3 changes: 2 additions & 1 deletion src/textual/drivers/linux_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from typing import TYPE_CHECKING, Any

import rich.repr
import rich.traceback

from .. import events
from .._xterm_parser import XTermParser
Expand Down Expand Up @@ -242,6 +241,8 @@ def _run_input_thread(self) -> None:
try:
self.run_input_thread()
except BaseException as error:
import rich.traceback

self._app.call_later(
self._app.panic,
rich.traceback.Traceback(),
Expand Down
3 changes: 1 addition & 2 deletions src/textual/message_pump.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@
import asyncio
import inspect
import threading
from asyncio import CancelledError, Queue, QueueEmpty, Task
from asyncio import CancelledError, Queue, QueueEmpty, Task, create_task
from contextlib import contextmanager
from functools import partial
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Generator, Iterable, cast
from weakref import WeakSet

from . import Logger, events, log, messages
from ._asyncio import create_task
from ._callback import invoke
from ._context import NoActiveAppError, active_app, active_message_pump
from ._context import message_hook as message_hook_context_var
Expand Down
3 changes: 1 addition & 2 deletions src/textual/timer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
from __future__ import annotations

import weakref
from asyncio import CancelledError, Event, Task
from asyncio import CancelledError, Event, Task, create_task
from typing import Any, Awaitable, Callable, Union

from rich.repr import Result, rich_repr

from . import _time, events
from ._asyncio import create_task
from ._callback import invoke
from ._context import active_app
from ._time import sleep
Expand Down
6 changes: 3 additions & 3 deletions src/textual/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from __future__ import annotations

from asyncio import wait
from asyncio import create_task, wait
from collections import Counter
from fractions import Fraction
from itertools import islice
Expand Down Expand Up @@ -37,13 +37,11 @@
from rich.segment import Segment
from rich.style import Style
from rich.text import Text
from rich.traceback import Traceback
from typing_extensions import Self

from . import constants, errors, events, messages
from ._animator import DEFAULT_EASING, Animatable, BoundAnimator, EasingFunction
from ._arrange import DockArrangeResult, arrange
from ._asyncio import create_task
from ._cache import FIFOCache
from ._compose import compose
from ._context import NoActiveAppError, active_app
Expand Down Expand Up @@ -3305,6 +3303,8 @@ async def _on_compose(self) -> None:
f"{self!r} compose() method returned an invalid result; {error}"
) from error
except Exception:
from rich.traceback import Traceback

self.app.panic(Traceback())
else:
self._extend_compose(widgets)
Expand Down
3 changes: 2 additions & 1 deletion src/textual/widgets/_markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from markdown_it.token import Token
from rich import box
from rich.style import Style
from rich.syntax import Syntax
from rich.table import Table
from rich.text import Text
from typing_extensions import TypeAlias
Expand Down Expand Up @@ -503,6 +502,8 @@ def __init__(self, markdown: Markdown, code: str, lexer: str) -> None:
super().__init__(markdown)

def compose(self) -> ComposeResult:
from rich.syntax import Syntax

yield Static(
Syntax(
self.code,
Expand Down
3 changes: 2 additions & 1 deletion src/textual/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
)

import rich.repr
from rich.traceback import Traceback
from typing_extensions import TypeAlias

from .message import Message
Expand Down Expand Up @@ -369,6 +368,8 @@ async def _run(self, app: App) -> None:
self.state = WorkerState.ERROR
self._error = error
app.log.worker(self, "failed", repr(error))
from rich.traceback import Traceback

app.log.worker(Traceback())
if self.exit_on_error:
app._fatal_error()
Expand Down

0 comments on commit 02d3b98

Please sign in to comment.