diff --git a/conftest.py b/conftest.py index 0a5fee8f9..fe1c58050 100644 --- a/conftest.py +++ b/conftest.py @@ -8,7 +8,8 @@ https://docs.pytest.org/en/stable/deprecations.html """ -import pathlib +from __future__ import annotations + import shutil import typing as t @@ -21,6 +22,9 @@ from libtmux.session import Session from libtmux.window import Window +if t.TYPE_CHECKING: + import pathlib + pytest_plugins = ["pytester"] diff --git a/docs/conf.py b/docs/conf.py index dcdffada2..fb1d2359e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,8 @@ # flake8: NOQA: E501 """Sphinx configuration for libtmux.""" +from __future__ import annotations + import contextlib import inspect import pathlib @@ -72,7 +74,7 @@ html_extra_path = ["manifest.json"] html_theme = "furo" html_theme_path: list[str] = [] -html_theme_options: dict[str, t.Union[str, list[dict[str, str]]]] = { +html_theme_options: dict[str, str | list[dict[str, str]]] = { "light_logo": "img/libtmux.svg", "dark_logo": "img/libtmux.svg", "footer_icons": [ @@ -138,7 +140,7 @@ } -def linkcode_resolve(domain: str, info: dict[str, str]) -> t.Union[None, str]: +def linkcode_resolve(domain: str, info: dict[str, str]) -> None | str: """ Determine the URL corresponding to Python object. @@ -208,7 +210,7 @@ def linkcode_resolve(domain: str, info: dict[str, str]) -> t.Union[None, str]: ) -def remove_tabs_js(app: "Sphinx", exc: Exception) -> None: +def remove_tabs_js(app: Sphinx, exc: Exception) -> None: """Remove tabs.js from _static after build.""" # Fix for sphinx-inline-tabs#18 if app.builder.format == "html" and not exc: @@ -217,6 +219,6 @@ def remove_tabs_js(app: "Sphinx", exc: Exception) -> None: tabs_js.unlink() # When python 3.7 deprecated, use missing_ok=True -def setup(app: "Sphinx") -> None: +def setup(app: Sphinx) -> None: """Configure Sphinx app hooks.""" app.connect("build-finished", remove_tabs_js) diff --git a/src/libtmux/__about__.py b/src/libtmux/__about__.py index 1c1ca395a..2d0f7a5d7 100644 --- a/src/libtmux/__about__.py +++ b/src/libtmux/__about__.py @@ -1,5 +1,7 @@ """Metadata package for libtmux.""" +from __future__ import annotations + __title__ = "libtmux" __package_name__ = "libtmux" __version__ = "0.40.1" diff --git a/src/libtmux/__init__.py b/src/libtmux/__init__.py index d63fad198..9e3bb7693 100644 --- a/src/libtmux/__init__.py +++ b/src/libtmux/__init__.py @@ -1,5 +1,7 @@ """libtmux, a typed, pythonic API wrapper for the tmux terminal multiplexer.""" +from __future__ import annotations + from .__about__ import ( __author__, __copyright__, diff --git a/src/libtmux/_internal/dataclasses.py b/src/libtmux/_internal/dataclasses.py index add92f34a..19b4a2d5f 100644 --- a/src/libtmux/_internal/dataclasses.py +++ b/src/libtmux/_internal/dataclasses.py @@ -5,6 +5,8 @@ This is an internal API not covered by versioning policy. """ +from __future__ import annotations + import dataclasses import typing as t from operator import attrgetter @@ -78,7 +80,7 @@ class SkipDefaultFieldsReprMixin: ItemWithMixin(name=Test, unit_price=2.05) """ - def __repr__(self: "DataclassInstance") -> str: + def __repr__(self: DataclassInstance) -> str: """Omit default fields in object representation.""" nodef_f_vals = ( (f.name, attrgetter(f.name)(self)) diff --git a/src/libtmux/_internal/query_list.py b/src/libtmux/_internal/query_list.py index 150fa6b28..332968dbd 100644 --- a/src/libtmux/_internal/query_list.py +++ b/src/libtmux/_internal/query_list.py @@ -5,6 +5,8 @@ This is an internal API not covered by versioning policy. """ +from __future__ import annotations + import logging import re import traceback @@ -20,8 +22,8 @@ class LookupProtocol(t.Protocol): def __call__( self, - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: """Return callback for :class:`QueryList` filtering operators.""" ... @@ -41,9 +43,9 @@ class ObjectDoesNotExist(Exception): def keygetter( - obj: "Mapping[str, t.Any]", + obj: Mapping[str, t.Any], path: str, -) -> t.Union[None, t.Any, str, list[str], "Mapping[str, str]"]: +) -> None | t.Any | str | list[str] | Mapping[str, str]: """Fetch values in objects and keys, supported nested data. **With dictionaries**: @@ -112,10 +114,10 @@ def keygetter( def parse_lookup( - obj: "Mapping[str, t.Any]", + obj: Mapping[str, t.Any], path: str, lookup: str, -) -> t.Optional[t.Any]: +) -> t.Any | None: """Check if field lookup key, e.g. "my__path__contains" has comparator, return val. If comparator not used or value not found, return None. @@ -151,15 +153,15 @@ def parse_lookup( def lookup_exact( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: return rhs == data def lookup_iexact( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: if not isinstance(rhs, str) or not isinstance(data, str): return False @@ -168,8 +170,8 @@ def lookup_iexact( def lookup_contains( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: if not isinstance(rhs, str) or not isinstance(data, (str, Mapping, list)): return False @@ -178,8 +180,8 @@ def lookup_contains( def lookup_icontains( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: if not isinstance(rhs, str) or not isinstance(data, (str, Mapping, list)): return False @@ -193,8 +195,8 @@ def lookup_icontains( def lookup_startswith( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: if not isinstance(rhs, str) or not isinstance(data, str): return False @@ -203,8 +205,8 @@ def lookup_startswith( def lookup_istartswith( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: if not isinstance(rhs, str) or not isinstance(data, str): return False @@ -213,8 +215,8 @@ def lookup_istartswith( def lookup_endswith( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: if not isinstance(rhs, str) or not isinstance(data, str): return False @@ -223,8 +225,8 @@ def lookup_endswith( def lookup_iendswith( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: if not isinstance(rhs, str) or not isinstance(data, str): return False @@ -232,8 +234,8 @@ def lookup_iendswith( def lookup_in( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: if isinstance(rhs, list): return data in rhs @@ -254,8 +256,8 @@ def lookup_in( def lookup_nin( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: if isinstance(rhs, list): return data not in rhs @@ -276,8 +278,8 @@ def lookup_nin( def lookup_regex( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: if isinstance(data, (str, bytes, re.Pattern)) and isinstance(rhs, (str, bytes)): return bool(re.search(rhs, data)) @@ -285,15 +287,15 @@ def lookup_regex( def lookup_iregex( - data: t.Union[str, list[str], "Mapping[str, str]"], - rhs: t.Union[str, list[str], "Mapping[str, str]", "re.Pattern[str]"], + data: str | list[str] | Mapping[str, str], + rhs: str | list[str] | Mapping[str, str] | re.Pattern[str], ) -> bool: if isinstance(data, (str, bytes, re.Pattern)) and isinstance(rhs, (str, bytes)): return bool(re.search(rhs, data, re.IGNORECASE)) return False -LOOKUP_NAME_MAP: 'Mapping[str, "LookupProtocol"]' = { +LOOKUP_NAME_MAP: Mapping[str, LookupProtocol] = { "eq": lookup_exact, "exact": lookup_exact, "iexact": lookup_iexact, @@ -469,10 +471,10 @@ class QueryList(list[T], t.Generic[T]): [] """ - data: "Sequence[T]" - pk_key: t.Optional[str] + data: Sequence[T] + pk_key: str | None - def __init__(self, items: t.Optional["Iterable[T]"] = None) -> None: + def __init__(self, items: Iterable[T] | None = None) -> None: super().__init__(items if items is not None else []) def items(self) -> list[tuple[str, T]]: @@ -505,9 +507,9 @@ def __eq__( def filter( self, - matcher: t.Optional[t.Union[Callable[[T], bool], T]] = None, + matcher: Callable[[T], bool] | T | None = None, **kwargs: t.Any, - ) -> "QueryList[T]": + ) -> QueryList[T]: """Filter list of objects.""" def filter_lookup(obj: t.Any) -> bool: @@ -534,7 +536,7 @@ def filter_lookup(obj: t.Any) -> bool: filter_ = matcher elif matcher is not None: - def val_match(obj: t.Union[str, list[t.Any], T]) -> bool: + def val_match(obj: str | list[t.Any] | T) -> bool: if isinstance(matcher, list): return obj in matcher return bool(obj == matcher) @@ -547,10 +549,10 @@ def val_match(obj: t.Union[str, list[t.Any], T]) -> bool: def get( self, - matcher: t.Optional[t.Union[Callable[[T], bool], T]] = None, - default: t.Optional[t.Any] = no_arg, + matcher: Callable[[T], bool] | T | None = None, + default: t.Any | None = no_arg, **kwargs: t.Any, - ) -> t.Optional[T]: + ) -> T | None: """Retrieve one object. Raises :exc:`MultipleObjectsReturned` if multiple objects found. diff --git a/src/libtmux/_vendor/_structures.py b/src/libtmux/_vendor/_structures.py index 25c1775d8..c2fd421dd 100644 --- a/src/libtmux/_vendor/_structures.py +++ b/src/libtmux/_vendor/_structures.py @@ -2,6 +2,7 @@ # This file is dual licensed under the terms of the Apache License, Version # 2.0, and the BSD License. See the LICENSE file in the root of this repository # for complete details. +from __future__ import annotations class InfinityType: @@ -26,7 +27,7 @@ def __gt__(self, other: object) -> bool: def __ge__(self, other: object) -> bool: return True - def __neg__(self: object) -> "NegativeInfinityType": + def __neg__(self: object) -> NegativeInfinityType: return NegativeInfinity diff --git a/src/libtmux/_vendor/version.py b/src/libtmux/_vendor/version.py index 72af139db..f4d54be2a 100644 --- a/src/libtmux/_vendor/version.py +++ b/src/libtmux/_vendor/version.py @@ -9,10 +9,12 @@ from packaging.version import parse, Version """ +from __future__ import annotations + import collections import itertools import re -from typing import Callable, Optional, SupportsInt, Union +from typing import Callable, SupportsInt, Union from ._structures import Infinity, InfinityType, NegativeInfinity, NegativeInfinityType @@ -48,7 +50,7 @@ ) -def parse(version: str) -> "Version": +def parse(version: str) -> Version: """Parse the given version string. Examples @@ -91,13 +93,13 @@ def __hash__(self) -> int: # Please keep the duplicated `isinstance` check # in the six comparisons hereunder # unless you find a way to avoid adding overhead function calls. - def __lt__(self, other: "_BaseVersion") -> bool: + def __lt__(self, other: _BaseVersion) -> bool: if not isinstance(other, _BaseVersion): return NotImplemented return self._key < other._key - def __le__(self, other: "_BaseVersion") -> bool: + def __le__(self, other: _BaseVersion) -> bool: if not isinstance(other, _BaseVersion): return NotImplemented @@ -109,13 +111,13 @@ def __eq__(self, other: object) -> bool: return self._key == other._key - def __ge__(self, other: "_BaseVersion") -> bool: + def __ge__(self, other: _BaseVersion) -> bool: if not isinstance(other, _BaseVersion): return NotImplemented return self._key >= other._key - def __gt__(self, other: "_BaseVersion") -> bool: + def __gt__(self, other: _BaseVersion) -> bool: if not isinstance(other, _BaseVersion): return NotImplemented @@ -314,7 +316,7 @@ def release(self) -> tuple[int, ...]: return release @property - def pre(self) -> Optional[tuple[str, int]]: + def pre(self) -> tuple[str, int] | None: """The pre-release segment of the version. >>> print(Version("1.2.3").pre) @@ -326,11 +328,11 @@ def pre(self) -> Optional[tuple[str, int]]: >>> Version("1.2.3rc1").pre ('rc', 1) """ - pre: Optional[tuple[str, int]] = self._version.pre + pre: tuple[str, int] | None = self._version.pre return pre @property - def post(self) -> Optional[int]: + def post(self) -> int | None: """The post-release number of the version. >>> print(Version("1.2.3").post) @@ -341,7 +343,7 @@ def post(self) -> Optional[int]: return self._version.post[1] if self._version.post else None @property - def dev(self) -> Optional[int]: + def dev(self) -> int | None: """The development number of the version. >>> print(Version("1.2.3").dev) @@ -352,7 +354,7 @@ def dev(self) -> Optional[int]: return self._version.dev[1] if self._version.dev else None @property - def local(self) -> Optional[str]: + def local(self) -> str | None: """The local version segment of the version. >>> print(Version("1.2.3").local) @@ -475,8 +477,8 @@ def micro(self) -> int: def _parse_letter_version( letter: str, - number: Union[str, bytes, SupportsInt], -) -> Optional[tuple[str, int]]: + number: str | bytes | SupportsInt, +) -> tuple[str, int] | None: if letter: # We consider there to be an implicit 0 in a pre-release if there is # not a numeral associated with it. @@ -512,7 +514,7 @@ def _parse_letter_version( _local_version_separators = re.compile(r"[\._-]") -def _parse_local_version(local: str) -> Optional[LocalType]: +def _parse_local_version(local: str) -> LocalType | None: """Take a string like abc.1.twelve and turns it into ("abc", 1, "twelve").""" if local is not None: return tuple( @@ -525,10 +527,10 @@ def _parse_local_version(local: str) -> Optional[LocalType]: def _cmpkey( epoch: int, release: tuple[int, ...], - pre: Optional[tuple[str, int]], - post: Optional[tuple[str, int]], - dev: Optional[tuple[str, int]], - local: Optional[tuple[SubLocalType]], + pre: tuple[str, int] | None, + post: tuple[str, int] | None, + dev: tuple[str, int] | None, + local: tuple[SubLocalType] | None, ) -> CmpKey: # When we compare a release version, we want to compare it with all of the # trailing zeros removed. So we'll use a reverse the list, drop all the now diff --git a/src/libtmux/common.py b/src/libtmux/common.py index c62e304c7..83bfb5cd2 100644 --- a/src/libtmux/common.py +++ b/src/libtmux/common.py @@ -5,18 +5,21 @@ """ +from __future__ import annotations + import logging import re import shutil import subprocess import sys import typing as t -from collections.abc import Callable -from typing import Optional, Union from . import exc from ._compat import LooseVersion, console_to_str, str_from_console +if t.TYPE_CHECKING: + from collections.abc import Callable + logger = logging.getLogger(__name__) @@ -37,9 +40,9 @@ class EnvironmentMixin: _add_option = None - cmd: Callable[[t.Any, t.Any], "tmux_cmd"] + cmd: Callable[[t.Any, t.Any], tmux_cmd] - def __init__(self, add_option: Optional[str] = None) -> None: + def __init__(self, add_option: str | None = None) -> None: self._add_option = add_option def set_environment(self, name: str, value: str) -> None: @@ -117,7 +120,7 @@ def remove_environment(self, name: str) -> None: msg = f"tmux set-environment stderr: {cmd.stderr}" raise ValueError(msg) - def show_environment(self) -> dict[str, Union[bool, str]]: + def show_environment(self) -> dict[str, bool | str]: """Show environment ``$ tmux show-environment -t [session]``. Return dict of environment variables for the session. @@ -138,7 +141,7 @@ def show_environment(self) -> dict[str, Union[bool, str]]: cmd = self.cmd(*tmux_args) output = cmd.stdout opts = [tuple(item.split("=", 1)) for item in output] - opts_dict: dict[str, t.Union[str, bool]] = {} + opts_dict: dict[str, str | bool] = {} for _t in opts: if len(_t) == 2: opts_dict[_t[0]] = _t[1] @@ -149,7 +152,7 @@ def show_environment(self) -> dict[str, Union[bool, str]]: return opts_dict - def getenv(self, name: str) -> Optional[t.Union[str, bool]]: + def getenv(self, name: str) -> str | bool | None: """Show environment variable ``$ tmux show-environment -t [session] ``. Return the value of a specific variable if the name is specified. @@ -166,7 +169,7 @@ def getenv(self, name: str) -> Optional[t.Union[str, bool]]: str Value of environment variable """ - tmux_args: tuple[t.Union[str, int], ...] = () + tmux_args: tuple[str | int, ...] = () tmux_args += ("show-environment",) if self._add_option: @@ -175,7 +178,7 @@ def getenv(self, name: str) -> Optional[t.Union[str, bool]]: cmd = self.cmd(*tmux_args) output = cmd.stdout opts = [tuple(item.split("=", 1)) for item in output] - opts_dict: dict[str, t.Union[str, bool]] = {} + opts_dict: dict[str, str | bool] = {} for _t in opts: if len(_t) == 2: opts_dict[_t[0]] = _t[1] @@ -423,7 +426,7 @@ def has_minimum_version(raises: bool = True) -> bool: return True -def session_check_name(session_name: t.Optional[str]) -> None: +def session_check_name(session_name: str | None) -> None: """Raise exception session name invalid, modeled after tmux function. tmux(1) session names may not be empty, or include periods or colons. diff --git a/src/libtmux/constants.py b/src/libtmux/constants.py index 41698a8f0..b4c23ee64 100644 --- a/src/libtmux/constants.py +++ b/src/libtmux/constants.py @@ -1,5 +1,7 @@ """Constant variables for libtmux.""" +from __future__ import annotations + import enum diff --git a/src/libtmux/exc.py b/src/libtmux/exc.py index 2c665c335..430f17b53 100644 --- a/src/libtmux/exc.py +++ b/src/libtmux/exc.py @@ -5,6 +5,8 @@ """ +from __future__ import annotations + import typing as t from libtmux._internal.query_list import ObjectDoesNotExist @@ -30,10 +32,10 @@ class TmuxObjectDoesNotExist(ObjectDoesNotExist): def __init__( self, - obj_key: t.Optional[str] = None, - obj_id: t.Optional[str] = None, - list_cmd: t.Optional[str] = None, - list_extra_args: "t.Optional[ListExtraArgs]" = None, + obj_key: str | None = None, + obj_id: str | None = None, + list_cmd: str | None = None, + list_extra_args: ListExtraArgs | None = None, *args: object, ) -> None: if all(arg is not None for arg in [obj_key, obj_id, list_cmd, list_extra_args]): @@ -54,7 +56,7 @@ class BadSessionName(LibTmuxException): def __init__( self, reason: str, - session_name: t.Optional[str] = None, + session_name: str | None = None, *args: object, ) -> None: msg = f"Bad session name: {reason}" @@ -93,7 +95,7 @@ class WaitTimeout(LibTmuxException): class VariableUnpackingError(LibTmuxException): """Error unpacking variable.""" - def __init__(self, variable: t.Optional[t.Any] = None, *args: object) -> None: + def __init__(self, variable: t.Any | None = None, *args: object) -> None: return super().__init__(f"Unexpected variable: {variable!s}") @@ -104,7 +106,7 @@ class PaneError(LibTmuxException): class PaneNotFound(PaneError): """Pane not found.""" - def __init__(self, pane_id: t.Optional[str] = None, *args: object) -> None: + def __init__(self, pane_id: str | None = None, *args: object) -> None: if pane_id is not None: return super().__init__(f"Pane not found: {pane_id}") return super().__init__("Pane not found") diff --git a/src/libtmux/formats.py b/src/libtmux/formats.py index e6e60c370..a14d10486 100644 --- a/src/libtmux/formats.py +++ b/src/libtmux/formats.py @@ -7,6 +7,8 @@ """ +from __future__ import annotations + import os FORMAT_SEPARATOR = os.environ.get("LIBTMUX_TMUX_FORMAT_SEPARATOR", "␞") diff --git a/src/libtmux/neo.py b/src/libtmux/neo.py index bc4785cc0..ab5cd712b 100644 --- a/src/libtmux/neo.py +++ b/src/libtmux/neo.py @@ -1,5 +1,7 @@ """Tools for hydrating tmux data into python dataclass objects.""" +from __future__ import annotations + import dataclasses import logging import typing as t @@ -36,143 +38,143 @@ class Obj: """Dataclass of generic tmux object.""" - server: "Server" + server: Server - active_window_index: t.Union[str, None] = None - alternate_saved_x: t.Union[str, None] = None - alternate_saved_y: t.Union[str, None] = None + active_window_index: str | None = None + alternate_saved_x: str | None = None + alternate_saved_y: str | None = None # See QUIRK_TMUX_3_1_X_0001 - buffer_name: t.Union[str, None] = None - buffer_sample: t.Union[str, None] = None - buffer_size: t.Union[str, None] = None + buffer_name: str | None = None + buffer_sample: str | None = None + buffer_size: str | None = None # See QUIRK_TMUX_3_1_X_0001 - client_cell_height: t.Union[str, None] = None - client_cell_width: t.Union[str, None] = None + client_cell_height: str | None = None + client_cell_width: str | None = None # See QUIRK_TMUX_3_1_X_0001 - client_discarded: t.Union[str, None] = None - client_flags: t.Union[str, None] = None - client_height: t.Union[str, None] = None - client_key_table: t.Union[str, None] = None - client_name: t.Union[str, None] = None - client_pid: t.Union[str, None] = None - client_termname: t.Union[str, None] = None - client_tty: t.Union[str, None] = None - client_uid: t.Union[str, None] = None - client_user: t.Union[str, None] = None - client_width: t.Union[str, None] = None - client_written: t.Union[str, None] = None - command_list_alias: t.Union[str, None] = None - command_list_name: t.Union[str, None] = None - command_list_usage: t.Union[str, None] = None - config_files: t.Union[str, None] = None - copy_cursor_line: t.Union[str, None] = None - copy_cursor_word: t.Union[str, None] = None - copy_cursor_x: t.Union[str, None] = None - copy_cursor_y: t.Union[str, None] = None - current_file: t.Union[str, None] = None - cursor_character: t.Union[str, None] = None - cursor_flag: t.Union[str, None] = None - cursor_x: t.Union[str, None] = None - cursor_y: t.Union[str, None] = None - history_bytes: t.Union[str, None] = None - history_limit: t.Union[str, None] = None - history_size: t.Union[str, None] = None - insert_flag: t.Union[str, None] = None - keypad_cursor_flag: t.Union[str, None] = None - keypad_flag: t.Union[str, None] = None - last_window_index: t.Union[str, None] = None - line: t.Union[str, None] = None - mouse_all_flag: t.Union[str, None] = None - mouse_any_flag: t.Union[str, None] = None - mouse_button_flag: t.Union[str, None] = None - mouse_sgr_flag: t.Union[str, None] = None - mouse_standard_flag: t.Union[str, None] = None - next_session_id: t.Union[str, None] = None - origin_flag: t.Union[str, None] = None - pane_active: t.Union[str, None] = None # Not detected by script - pane_at_bottom: t.Union[str, None] = None - pane_at_left: t.Union[str, None] = None - pane_at_right: t.Union[str, None] = None - pane_at_top: t.Union[str, None] = None - pane_bg: t.Union[str, None] = None - pane_bottom: t.Union[str, None] = None - pane_current_command: t.Union[str, None] = None - pane_current_path: t.Union[str, None] = None - pane_dead_signal: t.Union[str, None] = None - pane_dead_status: t.Union[str, None] = None - pane_dead_time: t.Union[str, None] = None - pane_fg: t.Union[str, None] = None - pane_height: t.Union[str, None] = None - pane_id: t.Union[str, None] = None - pane_index: t.Union[str, None] = None - pane_left: t.Union[str, None] = None - pane_pid: t.Union[str, None] = None - pane_right: t.Union[str, None] = None - pane_search_string: t.Union[str, None] = None - pane_start_command: t.Union[str, None] = None - pane_start_path: t.Union[str, None] = None - pane_tabs: t.Union[str, None] = None - pane_top: t.Union[str, None] = None - pane_tty: t.Union[str, None] = None - pane_width: t.Union[str, None] = None - pid: t.Union[str, None] = None - scroll_position: t.Union[str, None] = None - scroll_region_lower: t.Union[str, None] = None - scroll_region_upper: t.Union[str, None] = None - search_match: t.Union[str, None] = None - selection_end_x: t.Union[str, None] = None - selection_end_y: t.Union[str, None] = None - selection_start_x: t.Union[str, None] = None - selection_start_y: t.Union[str, None] = None - session_activity: t.Union[str, None] = None - session_alerts: t.Union[str, None] = None - session_attached: t.Union[str, None] = None - session_attached_list: t.Union[str, None] = None - session_created: t.Union[str, None] = None - session_group: t.Union[str, None] = None - session_group_attached: t.Union[str, None] = None - session_group_list: t.Union[str, None] = None - session_group_size: t.Union[str, None] = None - session_id: t.Union[str, None] = None - session_last_attached: t.Union[str, None] = None - session_name: t.Union[str, None] = None - session_path: t.Union[str, None] = None - session_stack: t.Union[str, None] = None - session_windows: t.Union[str, None] = None - socket_path: t.Union[str, None] = None - start_time: t.Union[str, None] = None - uid: t.Union[str, None] = None - user: t.Union[str, None] = None - version: t.Union[str, None] = None - window_active: t.Union[str, None] = None # Not detected by script - window_active_clients: t.Union[str, None] = None - window_active_sessions: t.Union[str, None] = None - window_activity: t.Union[str, None] = None - window_cell_height: t.Union[str, None] = None - window_cell_width: t.Union[str, None] = None - window_height: t.Union[str, None] = None - window_id: t.Union[str, None] = None - window_index: t.Union[str, None] = None - window_layout: t.Union[str, None] = None - window_linked: t.Union[str, None] = None - window_linked_sessions: t.Union[str, None] = None - window_linked_sessions_list: t.Union[str, None] = None - window_marked_flag: t.Union[str, None] = None - window_name: t.Union[str, None] = None - window_offset_x: t.Union[str, None] = None - window_offset_y: t.Union[str, None] = None - window_panes: t.Union[str, None] = None - window_raw_flags: t.Union[str, None] = None - window_stack_index: t.Union[str, None] = None - window_width: t.Union[str, None] = None - wrap_flag: t.Union[str, None] = None + client_discarded: str | None = None + client_flags: str | None = None + client_height: str | None = None + client_key_table: str | None = None + client_name: str | None = None + client_pid: str | None = None + client_termname: str | None = None + client_tty: str | None = None + client_uid: str | None = None + client_user: str | None = None + client_width: str | None = None + client_written: str | None = None + command_list_alias: str | None = None + command_list_name: str | None = None + command_list_usage: str | None = None + config_files: str | None = None + copy_cursor_line: str | None = None + copy_cursor_word: str | None = None + copy_cursor_x: str | None = None + copy_cursor_y: str | None = None + current_file: str | None = None + cursor_character: str | None = None + cursor_flag: str | None = None + cursor_x: str | None = None + cursor_y: str | None = None + history_bytes: str | None = None + history_limit: str | None = None + history_size: str | None = None + insert_flag: str | None = None + keypad_cursor_flag: str | None = None + keypad_flag: str | None = None + last_window_index: str | None = None + line: str | None = None + mouse_all_flag: str | None = None + mouse_any_flag: str | None = None + mouse_button_flag: str | None = None + mouse_sgr_flag: str | None = None + mouse_standard_flag: str | None = None + next_session_id: str | None = None + origin_flag: str | None = None + pane_active: str | None = None # Not detected by script + pane_at_bottom: str | None = None + pane_at_left: str | None = None + pane_at_right: str | None = None + pane_at_top: str | None = None + pane_bg: str | None = None + pane_bottom: str | None = None + pane_current_command: str | None = None + pane_current_path: str | None = None + pane_dead_signal: str | None = None + pane_dead_status: str | None = None + pane_dead_time: str | None = None + pane_fg: str | None = None + pane_height: str | None = None + pane_id: str | None = None + pane_index: str | None = None + pane_left: str | None = None + pane_pid: str | None = None + pane_right: str | None = None + pane_search_string: str | None = None + pane_start_command: str | None = None + pane_start_path: str | None = None + pane_tabs: str | None = None + pane_top: str | None = None + pane_tty: str | None = None + pane_width: str | None = None + pid: str | None = None + scroll_position: str | None = None + scroll_region_lower: str | None = None + scroll_region_upper: str | None = None + search_match: str | None = None + selection_end_x: str | None = None + selection_end_y: str | None = None + selection_start_x: str | None = None + selection_start_y: str | None = None + session_activity: str | None = None + session_alerts: str | None = None + session_attached: str | None = None + session_attached_list: str | None = None + session_created: str | None = None + session_group: str | None = None + session_group_attached: str | None = None + session_group_list: str | None = None + session_group_size: str | None = None + session_id: str | None = None + session_last_attached: str | None = None + session_name: str | None = None + session_path: str | None = None + session_stack: str | None = None + session_windows: str | None = None + socket_path: str | None = None + start_time: str | None = None + uid: str | None = None + user: str | None = None + version: str | None = None + window_active: str | None = None # Not detected by script + window_active_clients: str | None = None + window_active_sessions: str | None = None + window_activity: str | None = None + window_cell_height: str | None = None + window_cell_width: str | None = None + window_height: str | None = None + window_id: str | None = None + window_index: str | None = None + window_layout: str | None = None + window_linked: str | None = None + window_linked_sessions: str | None = None + window_linked_sessions_list: str | None = None + window_marked_flag: str | None = None + window_name: str | None = None + window_offset_x: str | None = None + window_offset_y: str | None = None + window_panes: str | None = None + window_raw_flags: str | None = None + window_stack_index: str | None = None + window_width: str | None = None + wrap_flag: str | None = None def _refresh( self, obj_key: str, obj_id: str, - list_cmd: "ListCmd" = "list-panes", - list_extra_args: "t.Optional[ListExtraArgs]" = None, + list_cmd: ListCmd = "list-panes", + list_extra_args: ListExtraArgs | None = None, ) -> None: assert isinstance(obj_id, str) obj = fetch_obj( @@ -189,14 +191,14 @@ def _refresh( def fetch_objs( - server: "Server", - list_cmd: "ListCmd", - list_extra_args: "t.Optional[ListExtraArgs]" = None, + server: Server, + list_cmd: ListCmd, + list_extra_args: ListExtraArgs | None = None, ) -> OutputsRaw: """Fetch a listing of raw data from a tmux command.""" formats = list(Obj.__dataclass_fields__.keys()) - cmd_args: list[t.Union[str, int]] = [] + cmd_args: list[str | int] = [] if server.socket_name: cmd_args.insert(0, f"-L{server.socket_name}") @@ -231,11 +233,11 @@ def fetch_objs( def fetch_obj( - server: "Server", + server: Server, obj_key: str, obj_id: str, - list_cmd: "ListCmd" = "list-panes", - list_extra_args: "t.Optional[ListExtraArgs]" = None, + list_cmd: ListCmd = "list-panes", + list_extra_args: ListExtraArgs | None = None, ) -> OutputRaw: """Fetch raw data from tmux command.""" obj_formatters_filtered = fetch_objs( diff --git a/src/libtmux/pane.py b/src/libtmux/pane.py index 9586e68e5..d17212839 100644 --- a/src/libtmux/pane.py +++ b/src/libtmux/pane.py @@ -5,6 +5,8 @@ """ +from __future__ import annotations + import dataclasses import logging import pathlib @@ -74,7 +76,7 @@ class Pane(Obj): Accessed April 1st, 2018. """ - server: "Server" + server: Server def refresh(self) -> None: """Refresh pane attributes from tmux.""" @@ -86,7 +88,7 @@ def refresh(self) -> None: ) @classmethod - def from_pane_id(cls, server: "Server", pane_id: str) -> "Pane": + def from_pane_id(cls, server: Server, pane_id: str) -> Pane: """Create Pane from existing pane_id.""" pane = fetch_obj( obj_key="pane_id", @@ -101,7 +103,7 @@ def from_pane_id(cls, server: "Server", pane_id: str) -> "Pane": # Relations # @property - def window(self) -> "Window": + def window(self) -> Window: """Parent window of pane.""" assert isinstance(self.window_id, str) from libtmux.window import Window @@ -109,7 +111,7 @@ def window(self) -> "Window": return Window.from_window_id(server=self.server, window_id=self.window_id) @property - def session(self) -> "Session": + def session(self) -> Session: """Parent session of pane.""" return self.window.session @@ -121,7 +123,7 @@ def cmd( self, cmd: str, *args: t.Any, - target: t.Optional[t.Union[str, int]] = None, + target: str | int | None = None, ) -> tmux_cmd: """Execute tmux subcommand within pane context. @@ -161,18 +163,18 @@ def resize( self, /, # Adjustments - adjustment_direction: t.Optional[ResizeAdjustmentDirection] = None, - adjustment: t.Optional[int] = None, + adjustment_direction: ResizeAdjustmentDirection | None = None, + adjustment: int | None = None, # Manual - height: t.Optional[t.Union[str, int]] = None, - width: t.Optional[t.Union[str, int]] = None, + height: str | int | None = None, + width: str | int | None = None, # Zoom - zoom: t.Optional[bool] = None, + zoom: bool | None = None, # Mouse - mouse: t.Optional[bool] = None, + mouse: bool | None = None, # Optional flags - trim_below: t.Optional[bool] = None, - ) -> "Pane": + trim_below: bool | None = None, + ) -> Pane: """Resize tmux pane. Parameters @@ -260,9 +262,9 @@ def resize( def capture_pane( self, - start: t.Union["t.Literal['-']", t.Optional[int]] = None, - end: t.Union["t.Literal['-']", t.Optional[int]] = None, - ) -> t.Union[str, list[str]]: + start: t.Literal["-"] | int | None = None, + end: t.Literal["-"] | int | None = None, + ) -> str | list[str]: """Capture text from pane. ``$ tmux capture-pane`` to pane. @@ -297,9 +299,9 @@ def capture_pane( def send_keys( self, cmd: str, - enter: t.Optional[bool] = True, - suppress_history: t.Optional[bool] = False, - literal: t.Optional[bool] = False, + enter: bool | None = True, + suppress_history: bool | None = False, + literal: bool | None = False, ) -> None: r"""``$ tmux send-keys`` to the pane. @@ -351,17 +353,17 @@ def send_keys( def display_message( self, cmd: str, - get_text: "t.Literal[True]", - ) -> t.Union[str, list[str]]: ... + get_text: t.Literal[True], + ) -> str | list[str]: ... @overload - def display_message(self, cmd: str, get_text: "t.Literal[False]") -> None: ... + def display_message(self, cmd: str, get_text: t.Literal[False]) -> None: ... def display_message( self, cmd: str, get_text: bool = False, - ) -> t.Optional[t.Union[str, list[str]]]: + ) -> str | list[str] | None: """Display message to pane. Displays a message in target-client status line. @@ -382,7 +384,7 @@ def display_message( def kill( self, - all_except: t.Optional[bool] = None, + all_except: bool | None = None, ) -> None: """Kill :class:`Pane`. @@ -443,7 +445,7 @@ def kill( additional scoped window info. """ - def select(self) -> "Pane": + def select(self) -> Pane: """Select pane. Examples @@ -476,7 +478,7 @@ def select(self) -> "Pane": return self - def select_pane(self) -> "Pane": + def select_pane(self) -> Pane: """Select pane. Notes @@ -499,16 +501,16 @@ def select_pane(self) -> "Pane": def split( self, /, - target: t.Optional[t.Union[int, str]] = None, - start_directory: t.Optional[str] = None, + target: int | str | None = None, + start_directory: str | None = None, attach: bool = False, - direction: t.Optional[PaneDirection] = None, - full_window_split: t.Optional[bool] = None, - zoom: t.Optional[bool] = None, - shell: t.Optional[str] = None, - size: t.Optional[t.Union[str, int]] = None, - environment: t.Optional[dict[str, str]] = None, - ) -> "Pane": + direction: PaneDirection | None = None, + full_window_split: bool | None = None, + zoom: bool | None = None, + shell: str | None = None, + size: str | int | None = None, + environment: dict[str, str] | None = None, + ) -> Pane: """Split window and return :class:`Pane`, by default beneath current pane. Parameters @@ -663,7 +665,7 @@ def split( Commands (helpers) """ - def set_width(self, width: int) -> "Pane": + def set_width(self, width: int) -> Pane: """Set pane width. Parameters @@ -674,7 +676,7 @@ def set_width(self, width: int) -> "Pane": self.resize_pane(width=width) return self - def set_height(self, height: int) -> "Pane": + def set_height(self, height: int) -> Pane: """Set pane height. Parameters @@ -685,7 +687,7 @@ def set_height(self, height: int) -> "Pane": self.resize_pane(height=height) return self - def enter(self) -> "Pane": + def enter(self) -> Pane: """Send carriage return to pane. ``$ tmux send-keys`` send Enter to the pane. @@ -693,12 +695,12 @@ def enter(self) -> "Pane": self.cmd("send-keys", "Enter") return self - def clear(self) -> "Pane": + def clear(self) -> Pane: """Clear pane.""" self.send_keys("reset") return self - def reset(self) -> "Pane": + def reset(self) -> Pane: """Reset and clear pane history.""" self.cmd("send-keys", r"-R \; clear-history") return self @@ -720,7 +722,7 @@ def __repr__(self) -> str: # Aliases # @property - def id(self) -> t.Optional[str]: + def id(self) -> str | None: """Alias of :attr:`Pane.pane_id`. >>> pane.id @@ -732,7 +734,7 @@ def id(self) -> t.Optional[str]: return self.pane_id @property - def index(self) -> t.Optional[str]: + def index(self) -> str | None: """Alias of :attr:`Pane.pane_index`. >>> pane.index @@ -744,7 +746,7 @@ def index(self) -> t.Optional[str]: return self.pane_index @property - def height(self) -> t.Optional[str]: + def height(self) -> str | None: """Alias of :attr:`Pane.pane_height`. >>> pane.height.isdigit() @@ -756,7 +758,7 @@ def height(self) -> t.Optional[str]: return self.pane_height @property - def width(self) -> t.Optional[str]: + def width(self) -> str | None: """Alias of :attr:`Pane.pane_width`. >>> pane.width.isdigit() @@ -820,15 +822,15 @@ def at_right(self) -> bool: # def split_window( self, - target: t.Optional[t.Union[int, str]] = None, + target: int | str | None = None, attach: bool = False, - start_directory: t.Optional[str] = None, + start_directory: str | None = None, vertical: bool = True, - shell: t.Optional[str] = None, - size: t.Optional[t.Union[str, int]] = None, - percent: t.Optional[int] = None, # deprecated - environment: t.Optional[dict[str, str]] = None, - ) -> "Pane": # New Pane, not self + shell: str | None = None, + size: str | int | None = None, + percent: int | None = None, # deprecated + environment: dict[str, str] | None = None, + ) -> Pane: # New Pane, not self """Split window at pane and return newly created :class:`Pane`. Parameters @@ -867,7 +869,7 @@ def split_window( environment=environment, ) - def get(self, key: str, default: t.Optional[t.Any] = None) -> t.Any: + def get(self, key: str, default: t.Any | None = None) -> t.Any: """Return key-based lookup. Deprecated by attributes. .. deprecated:: 0.16 @@ -902,18 +904,18 @@ def __getitem__(self, key: str) -> t.Any: def resize_pane( self, # Adjustments - adjustment_direction: t.Optional[ResizeAdjustmentDirection] = None, - adjustment: t.Optional[int] = None, + adjustment_direction: ResizeAdjustmentDirection | None = None, + adjustment: int | None = None, # Manual - height: t.Optional[t.Union[str, int]] = None, - width: t.Optional[t.Union[str, int]] = None, + height: str | int | None = None, + width: str | int | None = None, # Zoom - zoom: t.Optional[bool] = None, + zoom: bool | None = None, # Mouse - mouse: t.Optional[bool] = None, + mouse: bool | None = None, # Optional flags - trim_below: t.Optional[bool] = None, - ) -> "Pane": + trim_below: bool | None = None, + ) -> Pane: """Resize pane, deprecated by :meth:`Pane.resize`. .. deprecated:: 0.28 diff --git a/src/libtmux/pytest_plugin.py b/src/libtmux/pytest_plugin.py index 3dcca9963..aad746912 100644 --- a/src/libtmux/pytest_plugin.py +++ b/src/libtmux/pytest_plugin.py @@ -1,10 +1,11 @@ """libtmux pytest plugin.""" +from __future__ import annotations + import contextlib import getpass import logging import os -import pathlib import typing as t import pytest @@ -14,6 +15,8 @@ from libtmux.test import TEST_SESSION_PREFIX, get_test_session_name, namer if t.TYPE_CHECKING: + import pathlib + from libtmux.session import Session logger = logging.getLogger(__name__) @@ -189,7 +192,7 @@ def session( request: pytest.FixtureRequest, session_params: dict[str, t.Any], server: Server, -) -> "Session": +) -> Session: """Return new, temporary :class:`libtmux.Session`. >>> from libtmux.session import Session diff --git a/src/libtmux/server.py b/src/libtmux/server.py index 89ea2b90b..6bbf4fa2d 100644 --- a/src/libtmux/server.py +++ b/src/libtmux/server.py @@ -5,6 +5,8 @@ """ +from __future__ import annotations + import logging import os import pathlib @@ -104,10 +106,10 @@ class Server(EnvironmentMixin): def __init__( self, - socket_name: t.Optional[str] = None, - socket_path: t.Optional[t.Union[str, pathlib.Path]] = None, - config_file: t.Optional[str] = None, - colors: t.Optional[int] = None, + socket_name: str | None = None, + socket_path: str | pathlib.Path | None = None, + config_file: str | None = None, + colors: int | None = None, **kwargs: t.Any, ) -> None: EnvironmentMixin.__init__(self, "-g") @@ -178,7 +180,7 @@ def cmd( self, cmd: str, *args: t.Any, - target: t.Optional[t.Union[str, int]] = None, + target: str | int | None = None, ) -> tmux_cmd: """Execute tmux command respective of socket name and file, return output. @@ -227,8 +229,8 @@ def cmd( Renamed from ``.tmux`` to ``.cmd``. """ - svr_args: list[t.Union[str, int]] = [cmd] - cmd_args: list[t.Union[str, int]] = [] + svr_args: list[str | int] = [cmd] + cmd_args: list[str | int] = [] if self.socket_name: svr_args.insert(0, f"-L{self.socket_name}") if self.socket_path: @@ -311,7 +313,7 @@ def kill(self) -> None: """ self.cmd("kill-server") - def kill_session(self, target_session: t.Union[str, int]) -> "Server": + def kill_session(self, target_session: str | int) -> Server: """Kill tmux session. Parameters @@ -354,7 +356,7 @@ def switch_client(self, target_session: str) -> None: if proc.stderr: raise exc.LibTmuxException(proc.stderr) - def attach_session(self, target_session: t.Optional[str] = None) -> None: + def attach_session(self, target_session: str | None = None) -> None: """Attach tmux session. Parameters @@ -374,15 +376,15 @@ def attach_session(self, target_session: t.Optional[str] = None) -> None: def new_session( self, - session_name: t.Optional[str] = None, + session_name: str | None = None, kill_session: bool = False, attach: bool = False, - start_directory: t.Optional[str] = None, - window_name: t.Optional[str] = None, - window_command: t.Optional[str] = None, - x: t.Optional[t.Union[int, "DashLiteral"]] = None, - y: t.Optional[t.Union[int, "DashLiteral"]] = None, - environment: t.Optional[dict[str, str]] = None, + start_directory: str | None = None, + window_name: str | None = None, + window_command: str | None = None, + x: int | DashLiteral | None = None, + y: int | DashLiteral | None = None, + environment: dict[str, str] | None = None, *args: t.Any, **kwargs: t.Any, ) -> Session: @@ -476,7 +478,7 @@ def new_session( if env: del os.environ["TMUX"] - tmux_args: tuple[t.Union[str, int], ...] = ( + tmux_args: tuple[str | int, ...] = ( "-P", "-F#{session_id}", # output ) @@ -655,7 +657,7 @@ def _list_panes(self) -> list[PaneDict]: ) return [p.__dict__ for p in self.panes] - def _update_panes(self) -> "Server": + def _update_panes(self) -> Server: """Update internal pane data and return ``self`` for chainability. .. deprecated:: 0.16 @@ -674,7 +676,7 @@ def _update_panes(self) -> "Server": self._list_panes() return self - def get_by_id(self, session_id: str) -> t.Optional[Session]: + def get_by_id(self, session_id: str) -> Session | None: """Return session by id. Deprecated in favor of :meth:`.sessions.get()`. .. deprecated:: 0.16 @@ -707,7 +709,7 @@ def where(self, kwargs: dict[str, t.Any]) -> list[Session]: except IndexError: return [] - def find_where(self, kwargs: dict[str, t.Any]) -> t.Optional[Session]: + def find_where(self, kwargs: dict[str, t.Any]) -> Session | None: """Filter through sessions, return first :class:`Session`. .. deprecated:: 0.16 @@ -742,7 +744,7 @@ def _list_windows(self) -> list[WindowDict]: ) return [w.__dict__ for w in self.windows] - def _update_windows(self) -> "Server": + def _update_windows(self) -> Server: """Update internal window data and return ``self`` for chainability. .. deprecated:: 0.16 @@ -774,7 +776,7 @@ def _sessions(self) -> list[SessionDict]: ) return self._list_sessions() - def _list_sessions(self) -> list["SessionDict"]: + def _list_sessions(self) -> list[SessionDict]: """Return list of session object dictionaries. .. deprecated:: 0.16 @@ -807,7 +809,7 @@ def list_sessions(self) -> list[Session]: return self.sessions @property - def children(self) -> QueryList["Session"]: + def children(self) -> QueryList[Session]: """Was used by TmuxRelationalObject (but that's longer used in this class). .. deprecated:: 0.16 diff --git a/src/libtmux/session.py b/src/libtmux/session.py index 785459fd1..c7eaceec1 100644 --- a/src/libtmux/session.py +++ b/src/libtmux/session.py @@ -5,6 +5,8 @@ """ +from __future__ import annotations + import dataclasses import logging import pathlib @@ -12,7 +14,6 @@ import warnings from libtmux._internal.query_list import QueryList -from libtmux.common import tmux_cmd from libtmux.constants import WINDOW_DIRECTION_FLAG_MAP, WindowDirection from libtmux.formats import FORMAT_SEPARATOR from libtmux.neo import Obj, fetch_obj, fetch_objs @@ -30,6 +31,8 @@ ) if t.TYPE_CHECKING: + from libtmux.common import tmux_cmd + from .server import Server @@ -73,7 +76,7 @@ class Session(Obj, EnvironmentMixin): https://man.openbsd.org/tmux.1#DESCRIPTION. Accessed April 1st, 2018. """ - server: "Server" + server: Server def refresh(self) -> None: """Refresh session attributes from tmux.""" @@ -85,7 +88,7 @@ def refresh(self) -> None: ) @classmethod - def from_session_id(cls, server: "Server", session_id: str) -> "Session": + def from_session_id(cls, server: Server, session_id: str) -> Session: """Create Session from existing session_id.""" session = fetch_obj( obj_key="session_id", @@ -99,7 +102,7 @@ def from_session_id(cls, server: "Server", session_id: str) -> "Session": # Relations # @property - def windows(self) -> QueryList["Window"]: + def windows(self) -> QueryList[Window]: """Windows contained by session. Can be accessed via @@ -119,7 +122,7 @@ def windows(self) -> QueryList["Window"]: return QueryList(windows) @property - def panes(self) -> QueryList["Pane"]: + def panes(self) -> QueryList[Pane]: """Panes contained by session's windows. Can be accessed via @@ -145,7 +148,7 @@ def cmd( self, cmd: str, *args: t.Any, - target: t.Optional[t.Union[str, int]] = None, + target: str | int | None = None, ) -> tmux_cmd: """Execute tmux subcommand within session context. @@ -193,9 +196,9 @@ def cmd( def set_option( self, option: str, - value: t.Union[str, int], + value: str | int, global_: bool = False, - ) -> "Session": + ) -> Session: """Set option ``$ tmux set-option