diff --git a/src/textual/__init__.py b/src/textual/__init__.py index 2a45b7360..cd08af618 100644 --- a/src/textual/__init__.py +++ b/src/textual/__init__.py @@ -1,7 +1,6 @@ from __future__ import annotations import inspect -import sys from typing import Callable import rich.repr @@ -12,11 +11,7 @@ __all__ = ["log", "panic"] from ._context import active_app from ._log import LogGroup, LogVerbosity - -if sys.version_info >= (3, 10): - from typing import TypeAlias -else: # pragma: no cover - from typing_extensions import TypeAlias +from ._typing import TypeAlias LogCallable: TypeAlias = "Callable" diff --git a/src/textual/_border.py b/src/textual/_border.py index 7294e4fc0..dfcdf01ae 100644 --- a/src/textual/_border.py +++ b/src/textual/_border.py @@ -1,6 +1,5 @@ from __future__ import annotations -import sys from functools import lru_cache from typing import cast, Tuple, Union @@ -11,11 +10,7 @@ from rich.style import Style from .color import Color from .css.types import EdgeStyle, EdgeType - -if sys.version_info >= (3, 10): - from typing import TypeAlias -else: # pragma: no cover - from typing_extensions import TypeAlias +from ._typing import TypeAlias INNER = 1 OUTER = 2 diff --git a/src/textual/_compositor.py b/src/textual/_compositor.py index 2efdb0744..23f52b664 100644 --- a/src/textual/_compositor.py +++ b/src/textual/_compositor.py @@ -13,10 +13,9 @@ without having to render the entire screen. from __future__ import annotations -import sys from itertools import chain from operator import itemgetter -from typing import TYPE_CHECKING, Callable, Iterable, NamedTuple, cast +from typing import TYPE_CHECKING, Iterable, NamedTuple, cast import rich.repr from rich.console import Console, ConsoleOptions, RenderableType, RenderResult @@ -27,15 +26,9 @@ from rich.style import Style from . import errors from ._cells import cell_len from ._loop import loop_last -from ._profile import timer from ._types import Lines from .geometry import Offset, Region, Size - -if sys.version_info >= (3, 10): - from typing import TypeAlias -else: # pragma: no cover - from typing_extensions import TypeAlias - +from ._typing import TypeAlias if TYPE_CHECKING: from .widget import Widget diff --git a/src/textual/_layout.py b/src/textual/_layout.py index a516ff0fe..fc9f21173 100644 --- a/src/textual/_layout.py +++ b/src/textual/_layout.py @@ -1,22 +1,14 @@ from __future__ import annotations from abc import ABC, abstractmethod -import sys from typing import ClassVar, NamedTuple, TYPE_CHECKING - from .geometry import Region, Size, Spacing - -if sys.version_info >= (3, 10): - from typing import TypeAlias -else: # pragma: no cover - from typing_extensions import TypeAlias - +from ._typing import TypeAlias if TYPE_CHECKING: from .widget import Widget - ArrangeResult: TypeAlias = "tuple[list[WidgetPlacement], set[Widget]]" DockArrangeResult: TypeAlias = "tuple[list[WidgetPlacement], set[Widget], Spacing]" diff --git a/src/textual/_styles_cache.py b/src/textual/_styles_cache.py index ae795a12e..3cc5e7512 100644 --- a/src/textual/_styles_cache.py +++ b/src/textual/_styles_cache.py @@ -1,6 +1,5 @@ from __future__ import annotations -import sys from typing import TYPE_CHECKING, Callable, Iterable, List from rich.segment import Segment @@ -11,22 +10,16 @@ from ._filter import LineFilter from ._opacity import _apply_opacity from ._segment_tools import line_crop, line_pad, line_trim from ._types import Lines +from ._typing import TypeAlias from .color import Color from .geometry import Region, Size, Spacing from .renderables.text_opacity import TextOpacity from .renderables.tint import Tint -if sys.version_info >= (3, 10): - from typing import TypeAlias -else: # pragma: no cover - from typing_extensions import TypeAlias - - if TYPE_CHECKING: from .css.styles import StylesBase from .widget import Widget - RenderLineCallback: TypeAlias = Callable[[int], List[Segment]] diff --git a/src/textual/_types.py b/src/textual/_types.py index 60d943963..cfb4af035 100644 --- a/src/textual/_types.py +++ b/src/textual/_types.py @@ -1,13 +1,8 @@ -import sys from typing import Awaitable, Callable, List, TYPE_CHECKING, Union from rich.segment import Segment -if sys.version_info >= (3, 8): - from typing import Protocol -else: - from typing_extensions import Protocol - +from textual._typing import Protocol if TYPE_CHECKING: from .message import Message diff --git a/src/textual/_typing.py b/src/textual/_typing.py new file mode 100644 index 000000000..6532b9ba5 --- /dev/null +++ b/src/textual/_typing.py @@ -0,0 +1,11 @@ +import sys + +if sys.version_info >= (3, 10): + from typing import TypeAlias +else: # pragma: no cover + from typing_extensions import TypeAlias + +if sys.version_info >= (3, 8): + from typing import Final, Literal, Protocol, TypedDict +else: + from typing_extensions import Final, Literal, Protocol, TypedDict diff --git a/src/textual/app.py b/src/textual/app.py index d53495730..c74456c86 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -1,8 +1,6 @@ from __future__ import annotations import asyncio -from asyncio import Task -from contextlib import asynccontextmanager import inspect import io import os @@ -10,14 +8,14 @@ import platform import sys import unicodedata import warnings +from asyncio import Task +from contextlib import asynccontextmanager from contextlib import redirect_stderr, redirect_stdout from datetime import datetime from pathlib import Path, PurePath from time import perf_counter from typing import ( Any, - Callable, - Coroutine, Generic, Iterable, Type, @@ -29,9 +27,6 @@ from typing import ( ) from weakref import WeakSet, WeakValueDictionary -from ._ansi_sequences import SYNC_END, SYNC_START -from ._path import _make_path_object_relative - import nanoid import rich import rich.repr @@ -42,10 +37,13 @@ from rich.traceback import Traceback from . import Logger, LogGroup, LogVerbosity, actions, events, log, messages from ._animator import Animator, DEFAULT_EASING, Animatable, EasingFunction +from ._ansi_sequences import SYNC_END, SYNC_START from ._callback import invoke from ._context import active_app from ._event_broker import NoHandler, extract_handler_actions from ._filter import LineFilter, Monochrome +from ._path import _make_path_object_relative +from ._typing import TypeAlias from .binding import Binding, Bindings from .css.query import NoMatches from .css.stylesheet import Stylesheet @@ -67,11 +65,6 @@ if TYPE_CHECKING: from .devtools.client import DevtoolsClient from .pilot import Pilot -if sys.version_info >= (3, 10): - from typing import TypeAlias -else: # pragma: no cover - from typing_extensions import TypeAlias - PLATFORM = platform.system() WINDOWS = PLATFORM == "Windows" diff --git a/src/textual/binding.py b/src/textual/binding.py index 3ea032589..1398d5596 100644 --- a/src/textual/binding.py +++ b/src/textual/binding.py @@ -1,15 +1,11 @@ from __future__ import annotations -import sys from dataclasses import dataclass from typing import Iterable, MutableMapping import rich.repr -if sys.version_info >= (3, 10): - from typing import TypeAlias -else: # pragma: no cover - from typing_extensions import TypeAlias +from textual._typing import TypeAlias BindingType: TypeAlias = "Binding | tuple[str, str, str]" diff --git a/src/textual/css/_help_text.py b/src/textual/css/_help_text.py index e148426ed..3eafc0df4 100644 --- a/src/textual/css/_help_text.py +++ b/src/textual/css/_help_text.py @@ -1,9 +1,9 @@ from __future__ import annotations -import sys from dataclasses import dataclass -from typing import Iterable +from typing import Iterable, Sequence +from textual._typing import Literal from textual.color import ColorParseError from textual.css._help_renderables import Example, Bullet, HelpText from textual.css.constants import ( @@ -15,11 +15,6 @@ from textual.css.constants import ( VALID_TEXT_ALIGN, ) -if sys.version_info >= (3, 8): - from typing import Literal, Iterable, Sequence -else: - from typing_extensions import Literal - from textual.css._error_tools import friendly_list from textual.css.scalar import SYMBOL_UNIT diff --git a/src/textual/css/constants.py b/src/textual/css/constants.py index a59671753..e181af84a 100644 --- a/src/textual/css/constants.py +++ b/src/textual/css/constants.py @@ -1,13 +1,8 @@ from __future__ import annotations -import sys import typing -if sys.version_info >= (3, 8): - from typing import Final -else: - from typing_extensions import Final # pragma: no cover - from ..geometry import Spacing +from .._typing import Final if typing.TYPE_CHECKING: from .types import EdgeType diff --git a/src/textual/css/styles.py b/src/textual/css/styles.py index d830b6774..8efd8c22f 100644 --- a/src/textual/css/styles.py +++ b/src/textual/css/styles.py @@ -1,6 +1,5 @@ from __future__ import annotations -import sys from abc import ABC, abstractmethod from dataclasses import dataclass, field from functools import lru_cache @@ -60,11 +59,7 @@ from .types import ( Visibility, TextAlign, ) - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict +from .._typing import TypedDict if TYPE_CHECKING: from .._layout import Layout diff --git a/src/textual/css/types.py b/src/textual/css/types.py index 24958900c..b0f78c796 100644 --- a/src/textual/css/types.py +++ b/src/textual/css/types.py @@ -1,15 +1,9 @@ from __future__ import annotations -import sys from typing import Tuple from ..color import Color - -if sys.version_info >= (3, 8): - from typing import Literal -else: - from typing_extensions import Literal - +from .._typing import Literal Edge = Literal["top", "right", "bottom", "left"] DockEdge = Literal["top", "right", "bottom", "left", ""] diff --git a/src/textual/devtools/renderables.py b/src/textual/devtools/renderables.py index 4f6f40d7b..9d0b3091a 100644 --- a/src/textual/devtools/renderables.py +++ b/src/textual/devtools/renderables.py @@ -1,17 +1,11 @@ from __future__ import annotations -import sys from datetime import datetime from pathlib import Path from typing import Iterable from importlib_metadata import version -if sys.version_info >= (3, 8): - from typing import Literal -else: - from typing_extensions import Literal - from rich.align import Align from rich.console import Console, ConsoleOptions, RenderResult from rich.markup import escape @@ -22,6 +16,7 @@ from rich.styled import Styled from rich.table import Table from rich.text import Text from textual._log import LogGroup +from textual._typing import Literal DevConsoleMessageLevel = Literal["info", "warning", "error"] diff --git a/src/textual/dom.py b/src/textual/dom.py index aa8f9a1b4..2efbb14b0 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -1,7 +1,6 @@ from __future__ import annotations import re -import sys from collections import deque from inspect import getfile from typing import ( @@ -42,20 +41,10 @@ if TYPE_CHECKING: from .screen import Screen from .widget import Widget -if sys.version_info >= (3, 8): - from typing import Literal -else: - from typing_extensions import Literal - -if sys.version_info >= (3, 10): - from typing import TypeAlias -else: # pragma: no cover - from typing_extensions import TypeAlias - +from textual._typing import Literal, TypeAlias _re_identifier = re.compile(IDENTIFIER) - WalkMethod: TypeAlias = Literal["depth", "breadth"] diff --git a/src/textual/features.py b/src/textual/features.py index 3d7aa6c0a..03e46e84f 100644 --- a/src/textual/features.py +++ b/src/textual/features.py @@ -1,13 +1,7 @@ from __future__ import annotations -import sys - from typing import cast - -if sys.version_info >= (3, 8): - from typing import Final, Literal -else: - from typing_extensions import Final, Literal +from textual._typing import Final, Literal FEATURES: Final = {"devtools", "debug", "headless"} diff --git a/src/textual/geometry.py b/src/textual/geometry.py index fca75e382..4ecd9b313 100644 --- a/src/textual/geometry.py +++ b/src/textual/geometry.py @@ -6,15 +6,11 @@ Functions and classes to manage terminal geometry (anything involving coordinate from __future__ import annotations -import sys from functools import lru_cache from operator import attrgetter, itemgetter from typing import Any, Collection, NamedTuple, Tuple, TypeVar, Union, cast -if sys.version_info >= (3, 10): - from typing import TypeAlias -else: # pragma: no cover - from typing_extensions import TypeAlias +from textual._typing import TypeAlias SpacingDimensions: TypeAlias = Union[ int, Tuple[int], Tuple[int, int], Tuple[int, int, int, int] diff --git a/src/textual/screen.py b/src/textual/screen.py index f0d6752b9..c7ff3a2e5 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -1,6 +1,5 @@ from __future__ import annotations -import sys from typing import Iterable, Iterator import rich.repr @@ -13,14 +12,11 @@ from ._compositor import Compositor, MapGeometry from .timer import Timer from ._types import CallbackType from .geometry import Offset, Region, Size +from ._typing import Final from .reactive import Reactive from .renderables.blank import Blank from .widget import Widget -if sys.version_info >= (3, 8): - from typing import Final -else: - from typing_extensions import Final # Screen updates will be batched so that they don't happen more often than 60 times per second: UPDATE_PERIOD: Final = 1 / 60 diff --git a/src/textual/widget.py b/src/textual/widget.py index 9d1f50bb2..4588815d3 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -5,7 +5,6 @@ from fractions import Fraction from itertools import islice from operator import attrgetter from typing import ( - Awaitable, Generator, TYPE_CHECKING, ClassVar, diff --git a/src/textual/widgets/_button.py b/src/textual/widgets/_button.py index 60ac3ff42..02db405f1 100644 --- a/src/textual/widgets/_button.py +++ b/src/textual/widgets/_button.py @@ -1,14 +1,8 @@ from __future__ import annotations -import sys from functools import partial from typing import cast -if sys.version_info >= (3, 8): - from typing import Literal -else: - from typing_extensions import Literal # pragma: no cover - import rich.repr from rich.console import RenderableType from rich.text import Text, TextType @@ -18,6 +12,7 @@ from ..css._error_tools import friendly_list from ..message import Message from ..reactive import Reactive from ..widgets import Static +from .._typing import Literal ButtonVariant = Literal["default", "primary", "success", "warning", "error"] _VALID_BUTTON_VARIANTS = {"default", "primary", "success", "warning", "error"} diff --git a/src/textual/widgets/_data_table.py b/src/textual/widgets/_data_table.py index 8cc67cc21..d1ceb90b7 100644 --- a/src/textual/widgets/_data_table.py +++ b/src/textual/widgets/_data_table.py @@ -1,6 +1,5 @@ from __future__ import annotations -import sys from dataclasses import dataclass, field from itertools import chain, zip_longest from typing import ClassVar, Generic, Iterable, NamedTuple, TypeVar, cast @@ -14,18 +13,13 @@ from rich.text import Text, TextType from .. import events, messages from .._cache import LRUCache -from .._profile import timer from .._segment_tools import line_crop from .._types import Lines from ..geometry import Region, Size, Spacing, clamp from ..reactive import Reactive from ..render import measure from ..scroll_view import ScrollView - -if sys.version_info >= (3, 8): - from typing import Literal -else: - from typing_extensions import Literal +from .._typing import Literal CursorType = Literal["cell", "row", "column"] CELL: CursorType = "cell" @@ -115,16 +109,15 @@ class Coord(NamedTuple): class DataTable(ScrollView, Generic[CellType], can_focus=True): - DEFAULT_CSS = """ App.-dark DataTable { background:; } DataTable { background: $surface ; - color: $text; + color: $text; } - DataTable > .datatable--header { + DataTable > .datatable--header { text-style: bold; background: $primary; color: $text; @@ -136,7 +129,7 @@ class DataTable(ScrollView, Generic[CellType], can_focus=True): } DataTable > .datatable--odd-row { - + } DataTable > .datatable--even-row { diff --git a/tests/css/test_styles.py b/tests/css/test_styles.py index 8819a6839..8a257c0ad 100644 --- a/tests/css/test_styles.py +++ b/tests/css/test_styles.py @@ -1,16 +1,9 @@ -import sys from decimal import Decimal -if sys.version_info >= (3, 10): - from typing import Literal -else: # pragma: no cover - from typing_extensions import Literal - import pytest from rich.style import Style -from textual.app import ComposeResult from textual.color import Color from textual.css.errors import StyleValueError from textual.css.scalar import Scalar, Unit