From c5c5ec94b013e41705685ef44a2d964a7dcd567a Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 24 Mar 2024 09:03:46 -0500 Subject: [PATCH 1/3] refactor!(ruff): Run all automated fixes as of ruff 0.3.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ruff check --select ALL . --fix --unsafe-fixes --preview --show-fixes; ruff format . Fixed 144 errors: - conftest.py: 2 × I001 (unsorted-imports) 2 × PT003 (pytest-extraneous-scope-function) 1 × PIE790 (unnecessary-placeholder) 1 × TCH005 (empty-type-checking-block) 1 × TCH004 (runtime-import-in-type-checking-block) - docs/conf.py: 1 × RET505 (superfluous-else-return) - src/libtmux/_internal/query_list.py: 3 × RSE102 (unnecessary-paren-on-raise-exception) 2 × ANN204 (missing-return-type-special-method) 1 × T201 (print) 1 × PLR5501 (collapsible-else-if) 1 × RET505 (superfluous-else-return) 1 × RET506 (superfluous-else-raise) 1 × F841 (unused-variable) - src/libtmux/_vendor/version.py: 2 × PLR6201 (literal-membership) 1 × ANN204 (missing-return-type-special-method) 1 × RET505 (superfluous-else-return) 1 × RUF022 (unsorted-dunder-all) - src/libtmux/common.py: 6 × RET506 (superfluous-else-raise) 1 × RSE102 (unnecessary-paren-on-raise-exception) 1 × TCH005 (empty-type-checking-block) 1 × I001 (unsorted-imports) - src/libtmux/exc.py: 8 × ANN204 (missing-return-type-special-method) 2 × PIE790 (unnecessary-placeholder) 2 × COM812 (missing-trailing-comma) 2 × E303 (too-many-blank-lines) - src/libtmux/neo.py: 1 × E303 (too-many-blank-lines) 1 × RET504 (unnecessary-assign) - src/libtmux/pane.py: 3 × E266 (multiple-leading-hashes-for-block-comment) 2 × COM812 (missing-trailing-comma) 1 × RSE102 (unnecessary-paren-on-raise-exception) 1 × E303 (too-many-blank-lines) 1 × PLR1711 (useless-return) - src/libtmux/pytest_plugin.py: 3 × PT003 (pytest-extraneous-scope-function) 1 × PT001 (pytest-fixture-incorrect-parentheses-style) - src/libtmux/server.py: 2 × ISC001 (single-line-implicit-string-concatenation) 2 × RSE102 (unnecessary-paren-on-raise-exception) 2 × COM812 (missing-trailing-comma) 1 × RET505 (superfluous-else-return) 1 × SIM103 (needless-bool) - src/libtmux/session.py: 5 × COM812 (missing-trailing-comma) 2 × RSE102 (unnecessary-paren-on-raise-exception) 1 × RET506 (superfluous-else-raise) 1 × RET505 (superfluous-else-return) 1 × RET503 (implicit-return) 1 × PLR1711 (useless-return) 1 × E303 (too-many-blank-lines) - src/libtmux/test.py: 1 × RET506 (superfluous-else-raise) 1 × RSE102 (unnecessary-paren-on-raise-exception) - src/libtmux/window.py: 4 × COM812 (missing-trailing-comma) 2 × E266 (multiple-leading-hashes-for-block-comment) 1 × RSE102 (unnecessary-paren-on-raise-exception) 1 × E303 (too-many-blank-lines) 1 × PLR6201 (literal-membership) 1 × PLR1711 (useless-return) - tests/_internal/test_query_list.py: 38 × PT007 (pytest-parametrize-values-wrong-type) 1 × PT006 (pytest-parametrize-names-wrong-type) - tests/legacy_api/test_session.py: 1 × PT006 (pytest-parametrize-names-wrong-type) - tests/legacy_api/test_version.py: 1 × PT014 (pytest-duplicate-parametrize-test-cases) - tests/legacy_api/test_window.py: 1 × COM812 (missing-trailing-comma) 1 × PT006 (pytest-parametrize-names-wrong-type) - tests/test_dataclasses.py: 1 × COM812 (missing-trailing-comma) 1 × PT001 (pytest-fixture-incorrect-parentheses-style) - tests/test_session.py: 2 × COM812 (missing-trailing-comma) - tests/test_version.py: 1 × PT014 (pytest-duplicate-parametrize-test-cases) - tests/test_window.py: 3 × COM812 (missing-trailing-comma) 1 × PT006 (pytest-parametrize-names-wrong-type) --- conftest.py | 8 +- docs/conf.py | 17 ++-- src/libtmux/_internal/query_list.py | 23 +++-- src/libtmux/_vendor/version.py | 11 ++- src/libtmux/common.py | 20 ++--- src/libtmux/exc.py | 26 +++--- src/libtmux/neo.py | 6 +- src/libtmux/pane.py | 18 ++-- src/libtmux/pytest_plugin.py | 8 +- src/libtmux/server.py | 23 ++--- src/libtmux/session.py | 33 ++++--- src/libtmux/test.py | 5 +- src/libtmux/window.py | 26 +++--- tests/_internal/test_query_list.py | 132 ++++++++++++++-------------- tests/legacy_api/test_session.py | 2 +- tests/legacy_api/test_version.py | 1 - tests/legacy_api/test_window.py | 4 +- tests/test_dataclasses.py | 5 +- tests/test_session.py | 6 +- tests/test_version.py | 1 - tests/test_window.py | 10 ++- 21 files changed, 192 insertions(+), 193 deletions(-) diff --git a/conftest.py b/conftest.py index 75d635de4..03ceefe41 100644 --- a/conftest.py +++ b/conftest.py @@ -21,9 +21,6 @@ from libtmux.session import Session from libtmux.window import Window -if t.TYPE_CHECKING: - from libtmux.session import Session - pytest_plugins = ["pytester"] @@ -47,7 +44,7 @@ def add_doctest_fixtures( doctest_namespace["request"] = request -@pytest.fixture(autouse=True, scope="function") +@pytest.fixture(autouse=True) def set_home( monkeypatch: pytest.MonkeyPatch, user_path: pathlib.Path, @@ -56,12 +53,11 @@ def set_home( monkeypatch.setenv("HOME", str(user_path)) -@pytest.fixture(autouse=True, scope="function") +@pytest.fixture(autouse=True) def setup_fn( clear_env: None, ) -> None: """Function-level test configuration fixtures for pytest.""" - pass @pytest.fixture(autouse=True, scope="session") diff --git a/docs/conf.py b/docs/conf.py index ea4590744..88e4781ed 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -197,15 +197,14 @@ def linkcode_resolve(domain: str, info: t.Dict[str, str]) -> t.Union[None, str]: fn, linespec, ) - else: - return "{}/blob/v{}/{}/{}/{}{}".format( - about["__github__"], - about["__version__"], - "src", - about["__package_name__"], - fn, - linespec, - ) + return "{}/blob/v{}/{}/{}/{}{}".format( + about["__github__"], + about["__version__"], + "src", + about["__package_name__"], + fn, + linespec, + ) def remove_tabs_js(app: "Sphinx", exc: Exception) -> None: diff --git a/src/libtmux/_internal/query_list.py b/src/libtmux/_internal/query_list.py index 220c3f96c..997436b28 100644 --- a/src/libtmux/_internal/query_list.py +++ b/src/libtmux/_internal/query_list.py @@ -100,9 +100,8 @@ def keygetter( elif hasattr(dct, sub_field): dct = getattr(dct, sub_field) - except Exception as e: + except Exception: traceback.print_stack() - print(f"Above error was {e}") return None return dct @@ -307,12 +306,12 @@ def lookup_iregex( class PKRequiredException(Exception): - def __init__(self, *args: object): + def __init__(self, *args: object) -> None: return super().__init__("items() require a pk_key exists") class OpNotFound(ValueError): - def __init__(self, op: str, *args: object): + def __init__(self, op: str, *args: object) -> None: return super().__init__(f"{op} not in LOOKUP_NAME_MAP") @@ -473,7 +472,7 @@ def __init__(self, items: t.Optional["Iterable[T]"] = None) -> None: def items(self) -> t.List[t.Tuple[str, T]]: if self.pk_key is None: - raise PKRequiredException() + raise PKRequiredException return [(getattr(item, self.pk_key), item) for item in self] def __eq__( @@ -493,9 +492,8 @@ def __eq__( for key in a_keys: if abs(a[key] - b[key]) > 1: return False - else: - if a != b: - return False + elif a != b: + return False return True return False @@ -534,8 +532,7 @@ def filter_lookup(obj: t.Any) -> bool: def val_match(obj: t.Union[str, t.List[t.Any], T]) -> bool: if isinstance(matcher, list): return obj in matcher - else: - return bool(obj == matcher) + return bool(obj == matcher) _filter = val_match else: @@ -557,9 +554,9 @@ def get( """ objs = self.filter(matcher=matcher, **kwargs) if len(objs) > 1: - raise MultipleObjectsReturned() - elif len(objs) == 0: + raise MultipleObjectsReturned + if len(objs) == 0: if default == no_arg: - raise ObjectDoesNotExist() + raise ObjectDoesNotExist return default return objs[0] diff --git a/src/libtmux/_vendor/version.py b/src/libtmux/_vendor/version.py index 808b317bf..95d16d9d5 100644 --- a/src/libtmux/_vendor/version.py +++ b/src/libtmux/_vendor/version.py @@ -16,7 +16,7 @@ from ._structures import Infinity, InfinityType, NegativeInfinity, NegativeInfinityType -__all__ = ["VERSION_PATTERN", "parse", "Version", "InvalidVersion"] +__all__ = ["VERSION_PATTERN", "InvalidVersion", "Version", "parse"] InfiniteTypes = Union[InfinityType, NegativeInfinityType] PrePostDevType = Union[InfiniteTypes, Tuple[str, int]] @@ -78,7 +78,7 @@ class InvalidVersion(ValueError): libtmux._vendor.version.InvalidVersion: Invalid version: 'invalid' """ - def __init__(self, version: str, *args: object): + def __init__(self, version: str, *args: object) -> None: return super().__init__(f"Invalid version: '{version}'") @@ -362,8 +362,7 @@ def local(self) -> Optional[str]: """ if self._version.local: return ".".join(str(x) for x in self._version.local) - else: - return None + return None @property def public(self) -> str: @@ -494,9 +493,9 @@ def _parse_letter_version( letter = "a" elif letter == "beta": letter = "b" - elif letter in ["c", "pre", "preview"]: + elif letter in {"c", "pre", "preview"}: letter = "rc" - elif letter in ["rev", "r"]: + elif letter in {"rev", "r"}: letter = "post" return letter, int(number) diff --git a/src/libtmux/common.py b/src/libtmux/common.py index b127f71c8..94008a2a7 100644 --- a/src/libtmux/common.py +++ b/src/libtmux/common.py @@ -16,10 +16,6 @@ from . import exc from ._compat import LooseVersion, console_to_str, str_from_console -if t.TYPE_CHECKING: - pass - - logger = logging.getLogger(__name__) @@ -219,7 +215,7 @@ class tmux_cmd: def __init__(self, *args: t.Any) -> None: tmux_bin = shutil.which("tmux") if not tmux_bin: - raise exc.TmuxCommandNotFound() + raise exc.TmuxCommandNotFound cmd = [tmux_bin] cmd += args # add the command arguments to cmd @@ -416,8 +412,7 @@ def has_minimum_version(raises: bool = True) -> bool: + "libtmux." ) raise exc.VersionTooLow(msg) - else: - return False + return False return True @@ -439,9 +434,9 @@ def session_check_name(session_name: t.Optional[str]) -> None: """ if session_name is None or len(session_name) == 0: raise exc.BadSessionName(reason="empty", session_name=session_name) - elif "." in session_name: + if "." in session_name: raise exc.BadSessionName(reason="contains periods", session_name=session_name) - elif ":" in session_name: + if ":" in session_name: raise exc.BadSessionName(reason="contains colons", session_name=session_name) @@ -474,12 +469,11 @@ def handle_option_error(error: str) -> t.Type[exc.OptionError]: """ if "unknown option" in error: raise exc.UnknownOption(error) - elif "invalid option" in error: + if "invalid option" in error: raise exc.InvalidOption(error) - elif "ambiguous option" in error: + if "ambiguous option" in error: raise exc.AmbiguousOption(error) - else: - raise exc.OptionError(error) # Raise generic option error + raise exc.OptionError(error) # Raise generic option error def get_libtmux_version() -> LooseVersion: diff --git a/src/libtmux/exc.py b/src/libtmux/exc.py index 2ac52fe4e..2c665c335 100644 --- a/src/libtmux/exc.py +++ b/src/libtmux/exc.py @@ -35,7 +35,7 @@ def __init__( list_cmd: t.Optional[str] = None, list_extra_args: "t.Optional[ListExtraArgs]" = None, *args: object, - ): + ) -> None: if all(arg is not None for arg in [obj_key, obj_id, list_cmd, list_extra_args]): return super().__init__( f"Could not find {obj_key}={obj_id} for {list_cmd} " @@ -56,7 +56,7 @@ def __init__( reason: str, session_name: t.Optional[str] = None, *args: object, - ): + ) -> None: msg = f"Bad session name: {reason}" if session_name is not None: msg += f" (session name: {session_name})" @@ -74,7 +74,7 @@ class UnknownOption(OptionError): class UnknownColorOption(UnknownOption): """Unknown color option.""" - def __init__(self, *args: object): + def __init__(self, *args: object) -> None: return super().__init__("Server.colors must equal 88 or 256") @@ -93,7 +93,7 @@ class WaitTimeout(LibTmuxException): class VariableUnpackingError(LibTmuxException): """Error unpacking variable.""" - def __init__(self, variable: t.Optional[t.Any] = None, *args: object): + def __init__(self, variable: t.Optional[t.Any] = None, *args: object) -> None: return super().__init__(f"Unexpected variable: {variable!s}") @@ -104,7 +104,7 @@ class PaneError(LibTmuxException): class PaneNotFound(PaneError): """Pane not found.""" - def __init__(self, pane_id: t.Optional[str] = None, *args: object): + def __init__(self, pane_id: t.Optional[str] = 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") @@ -117,21 +117,21 @@ class WindowError(LibTmuxException): class MultipleActiveWindows(WindowError): """Multiple active windows.""" - def __init__(self, count: int, *args: object): + def __init__(self, count: int, *args: object) -> None: return super().__init__(f"Multiple active windows: {count} found") class NoActiveWindow(WindowError): """No active window found.""" - def __init__(self, *args: object): + def __init__(self, *args: object) -> None: return super().__init__("No active windows found") class NoWindowsExist(WindowError): """No windows exist for object.""" - def __init__(self, *args: object): + def __init__(self, *args: object) -> None: return super().__init__("No windows exist for object") @@ -143,20 +143,18 @@ def __init__(self) -> None: class WindowAdjustmentDirectionRequiresAdjustment( - WindowError, AdjustmentDirectionRequiresAdjustment + WindowError, + AdjustmentDirectionRequiresAdjustment, ): """ValueError for :meth:`libtmux.Window.resize_window`.""" - pass - class PaneAdjustmentDirectionRequiresAdjustment( - WindowError, AdjustmentDirectionRequiresAdjustment + WindowError, + AdjustmentDirectionRequiresAdjustment, ): """ValueError for :meth:`libtmux.Pane.resize_pane`.""" - pass - class RequiresDigitOrPercentage(LibTmuxException, ValueError): """Requires digit (int or str digit) or a percentage.""" diff --git a/src/libtmux/neo.py b/src/libtmux/neo.py index e5d3ae32e..bd84264b4 100644 --- a/src/libtmux/neo.py +++ b/src/libtmux/neo.py @@ -226,11 +226,7 @@ def fetch_objs( ] # Filter empty values - obj_formatters_filtered = [ - {k: v for k, v in formatter.items() if v} for formatter in obj_formatters - ] - - return obj_formatters_filtered + return [{k: v for k, v in formatter.items() if v} for formatter in obj_formatters] def fetch_obj( diff --git a/src/libtmux/pane.py b/src/libtmux/pane.py index 34d2cee7f..5cc04a449 100644 --- a/src/libtmux/pane.py +++ b/src/libtmux/pane.py @@ -215,16 +215,16 @@ def resize( """ tmux_args: t.Tuple[str, ...] = () - ## Adjustments + # Adjustments if adjustment_direction: if adjustment is None: - raise exc.PaneAdjustmentDirectionRequiresAdjustment() + raise exc.PaneAdjustmentDirectionRequiresAdjustment tmux_args += ( f"{RESIZE_ADJUSTMENT_DIRECTION_FLAG_MAP[adjustment_direction]}", str(adjustment), ) elif height or width: - ## Manual resizing + # Manual resizing if height: if isinstance(height, str): if height.endswith("%") and not has_gte_version("3.1"): @@ -242,7 +242,7 @@ def resize( tmux_args += (f"-x{width}",) elif zoom: - ## Zoom / Unzoom + # Zoom / Unzoom tmux_args += ("-Z",) elif mouse: tmux_args += ("-M",) @@ -436,8 +436,6 @@ def kill( if proc.stderr: raise exc.LibTmuxException(proc.stderr) - return None - """ Commands ("climber"-helpers) @@ -650,7 +648,9 @@ def split( raise exc.LibTmuxException(pane_cmd.stderr) raise exc.LibTmuxException( - pane_cmd.stderr, self.__dict__, self.window.panes + pane_cmd.stderr, + self.__dict__, + self.window.panes, ) pane_output = pane_cmd.stdout[0] @@ -877,7 +877,9 @@ def get(self, key: str, default: t.Optional[t.Any] = None) -> t.Any: """ warnings.warn( - "Pane.get() is deprecated", category=DeprecationWarning, stacklevel=2 + "Pane.get() is deprecated", + category=DeprecationWarning, + stacklevel=2, ) return getattr(self, key, default) diff --git a/src/libtmux/pytest_plugin.py b/src/libtmux/pytest_plugin.py index c0190f179..8a1611a64 100644 --- a/src/libtmux/pytest_plugin.py +++ b/src/libtmux/pytest_plugin.py @@ -77,7 +77,7 @@ def config_file(user_path: pathlib.Path) -> pathlib.Path: return c -@pytest.fixture +@pytest.fixture() def clear_env(monkeypatch: pytest.MonkeyPatch) -> None: """Clear out any unnecessary environment variables that could interrupt tests. @@ -105,7 +105,7 @@ def clear_env(monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.delenv(k) -@pytest.fixture(scope="function") +@pytest.fixture() def server( request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch, @@ -146,7 +146,7 @@ def fin() -> None: return server -@pytest.fixture(scope="function") +@pytest.fixture() def session_params() -> t.Dict[str, t.Any]: """Return new, temporary :class:`libtmux.Session`. @@ -184,7 +184,7 @@ def session_params() -> t.Dict[str, t.Any]: return {} -@pytest.fixture(scope="function") +@pytest.fixture() def session( request: pytest.FixtureRequest, session_params: t.Dict[str, t.Any], diff --git a/src/libtmux/server.py b/src/libtmux/server.py index 15a5fe0e4..e6c9da8aa 100644 --- a/src/libtmux/server.py +++ b/src/libtmux/server.py @@ -159,7 +159,7 @@ def raise_if_dead(self) -> None: """ tmux_bin = shutil.which("tmux") if tmux_bin is None: - raise exc.TmuxCommandNotFound() + raise exc.TmuxCommandNotFound cmd_args: t.List[str] = ["list-sessions"] if self.socket_name: @@ -241,7 +241,7 @@ def cmd( elif self.colors == 88: svr_args.insert(0, "-8") else: - raise exc.UnknownColorOption() + raise exc.UnknownColorOption cmd_args = ["-t", str(target), *args] if target is not None else [*args] @@ -289,10 +289,7 @@ def has_session(self, target_session: str, exact: bool = True) -> bool: proc = self.cmd("has-session", target=target_session) - if not proc.returncode: - return True - - return False + return bool(not proc.returncode) def kill(self) -> None: """Kill tmux server. @@ -613,9 +610,9 @@ def __repr__(self) -> str: f"{self.__class__.__name__}" f"(socket_name={getattr(self, 'socket_name', 'default')})" ) - elif self.socket_path is not None: - return f"{self.__class__.__name__}" f"(socket_path={self.socket_path})" - return f"{self.__class__.__name__}" f"(socket_path=/tmp/tmux-1000/default)" + if self.socket_path is not None: + return f"{self.__class__.__name__}(socket_path={self.socket_path})" + return f"{self.__class__.__name__}(socket_path=/tmp/tmux-1000/default)" # # Legacy: Redundant stuff we want to remove @@ -770,7 +767,9 @@ def _sessions(self) -> t.List[SessionDict]: """ warnings.warn( - "Server._sessions is deprecated", category=DeprecationWarning, stacklevel=2 + "Server._sessions is deprecated", + category=DeprecationWarning, + stacklevel=2, ) return self._list_sessions() @@ -816,6 +815,8 @@ def children(self) -> QueryList["Session"]: """ warnings.warn( - "Server.children is deprecated", category=DeprecationWarning, stacklevel=2 + "Server.children is deprecated", + category=DeprecationWarning, + stacklevel=2, ) return self.sessions diff --git a/src/libtmux/session.py b/src/libtmux/session.py index a1e1ca29f..0b6eb6437 100644 --- a/src/libtmux/session.py +++ b/src/libtmux/session.py @@ -142,7 +142,10 @@ def panes(self) -> QueryList["Pane"]: # Command # def cmd( - self, cmd: str, *args: t.Any, target: t.Optional[t.Union[str, int]] = None + self, + cmd: str, + *args: t.Any, + target: t.Optional[t.Union[str, int]] = None, ) -> tmux_cmd: """Execute tmux subcommand within session context. @@ -382,13 +385,13 @@ def active_window(self) -> "Window": if len(active_windows) == 1: return next(iter(active_windows)) - elif len(active_windows) == 0: - raise exc.NoActiveWindow() - else: - raise exc.MultipleActiveWindows(count=len(active_windows)) + if len(active_windows) == 0: + raise exc.NoActiveWindow + raise exc.MultipleActiveWindows(count=len(active_windows)) if len(self._windows) == 0: - raise exc.NoWindowsExist() + raise exc.NoWindowsExist + return None def attach( self, @@ -488,8 +491,6 @@ def kill( if proc.stderr: raise exc.LibTmuxException(proc.stderr) - return None - def switch_client(self) -> "Session": """Switch client to session. @@ -839,7 +840,9 @@ def get(self, key: str, default: t.Optional[t.Any] = None) -> t.Any: """ warnings.warn( - "Session.get() is deprecated", category=DeprecationWarning, stacklevel=2 + "Session.get() is deprecated", + category=DeprecationWarning, + stacklevel=2, ) return getattr(self, key, default) @@ -883,7 +886,9 @@ def where(self, kwargs: t.Dict[str, t.Any]) -> t.List[Window]: """ warnings.warn( - "Session.where() is deprecated", category=DeprecationWarning, stacklevel=2 + "Session.where() is deprecated", + category=DeprecationWarning, + stacklevel=2, ) try: return self.windows.filter(**kwargs) @@ -930,7 +935,9 @@ def _windows(self) -> t.List["WindowDict"]: """ warnings.warn( - "Session._windows is deprecated", category=DeprecationWarning, stacklevel=2 + "Session._windows is deprecated", + category=DeprecationWarning, + stacklevel=2, ) return self._list_windows() @@ -959,6 +966,8 @@ def children(self) -> QueryList["Window"]: """ warnings.warn( - "Session.children is deprecated", category=DeprecationWarning, stacklevel=2 + "Session.children is deprecated", + category=DeprecationWarning, + stacklevel=2, ) return self.windows diff --git a/src/libtmux/test.py b/src/libtmux/test.py index 6413b7b0b..fab0a07b3 100644 --- a/src/libtmux/test.py +++ b/src/libtmux/test.py @@ -102,9 +102,8 @@ def retry_until( end = time.time() if end - ini >= seconds: if raises: - raise WaitTimeout() - else: - return False + raise WaitTimeout + return False time.sleep(interval) return True diff --git a/src/libtmux/window.py b/src/libtmux/window.py index 7e1f11454..7d6d92b06 100644 --- a/src/libtmux/window.py +++ b/src/libtmux/window.py @@ -193,7 +193,7 @@ def select_pane(self, target_pane: t.Union[str, int]) -> t.Optional["Pane"]: ------- :class:`Pane` """ - if target_pane in ["-l", "-U", "-D", "-L", "-R"]: + if target_pane in {"-l", "-U", "-D", "-L", "-R"}: proc = self.cmd("select-pane", target_pane) else: proc = self.cmd("select-pane", target=target_pane) @@ -310,16 +310,16 @@ def resize( tmux_args: t.Tuple[str, ...] = () - ## Adjustments + # Adjustments if adjustment_direction: if adjustment is None: - raise exc.WindowAdjustmentDirectionRequiresAdjustment() + raise exc.WindowAdjustmentDirectionRequiresAdjustment tmux_args += ( f"{RESIZE_ADJUSTMENT_DIRECTION_FLAG_MAP[adjustment_direction]}", str(adjustment), ) elif height or width: - ## Manual resizing + # Manual resizing if height: tmux_args += (f"-y{int(height)}",) if width: @@ -591,8 +591,6 @@ def kill( if proc.stderr: raise exc.LibTmuxException(proc.stderr) - return None - def move_window( self, destination: str = "", @@ -934,7 +932,9 @@ def get(self, key: str, default: t.Optional[t.Any] = None) -> t.Any: """ warnings.warn( - "Window.get() is deprecated", category=DeprecationWarning, stacklevel=2 + "Window.get() is deprecated", + category=DeprecationWarning, + stacklevel=2, ) return getattr(self, key, default) @@ -978,7 +978,9 @@ def where(self, kwargs: t.Dict[str, t.Any]) -> t.List[Pane]: """ warnings.warn( - "Window.where() is deprecated", category=DeprecationWarning, stacklevel=2 + "Window.where() is deprecated", + category=DeprecationWarning, + stacklevel=2, ) try: return self.panes.filter(**kwargs) @@ -1036,7 +1038,9 @@ def list_panes(self) -> t.List["Pane"]: """ warnings.warn( - "list_panes() is deprecated", category=DeprecationWarning, stacklevel=2 + "list_panes() is deprecated", + category=DeprecationWarning, + stacklevel=2, ) return self.panes @@ -1050,6 +1054,8 @@ def children(self) -> QueryList["Pane"]: """ warnings.warn( - "Server.children is deprecated", category=DeprecationWarning, stacklevel=2 + "Server.children is deprecated", + category=DeprecationWarning, + stacklevel=2, ) return self.panes diff --git a/tests/_internal/test_query_list.py b/tests/_internal/test_query_list.py index d15636d0d..813ee3776 100644 --- a/tests/_internal/test_query_list.py +++ b/tests/_internal/test_query_list.py @@ -17,120 +17,120 @@ class Obj: @pytest.mark.parametrize( - "items,filter_expr,expected_result", + ("items", "filter_expr", "expected_result"), [ - [[Obj(test=1)], None, [Obj(test=1)]], - [[Obj(test=1)], {"test": 1}, [Obj(test=1)]], - [[Obj(test=1)], {"test": 2}, []], - [ + ([Obj(test=1)], None, [Obj(test=1)]), + ([Obj(test=1)], {"test": 1}, [Obj(test=1)]), + ([Obj(test=1)], {"test": 2}, []), + ( [Obj(test=2, fruit=["apple"])], {"fruit__in": "apple"}, QueryList([Obj(test=2, fruit=["apple"])]), - ], - [[{"test": 1}], None, [{"test": 1}]], - [[{"test": 1}], None, QueryList([{"test": 1}])], - [[{"fruit": "apple"}], None, QueryList([{"fruit": "apple"}])], - [ + ), + ([{"test": 1}], None, [{"test": 1}]), + ([{"test": 1}], None, QueryList([{"test": 1}])), + ([{"fruit": "apple"}], None, QueryList([{"fruit": "apple"}])), + ( [{"fruit": "apple", "banana": object()}], None, QueryList([{"fruit": "apple", "banana": object()}]), - ], - [ + ), + ( [{"fruit": "apple", "banana": object()}], {"fruit__eq": "apple"}, QueryList([{"fruit": "apple", "banana": object()}]), - ], - [ + ), + ( [{"fruit": "apple", "banana": object()}], {"fruit__eq": "notmatch"}, QueryList([]), - ], - [ + ), + ( [{"fruit": "apple", "banana": object()}], {"fruit__exact": "apple"}, QueryList([{"fruit": "apple", "banana": object()}]), - ], - [ + ), + ( [{"fruit": "apple", "banana": object()}], {"fruit__exact": "notmatch"}, QueryList([]), - ], - [ + ), + ( [{"fruit": "apple", "banana": object()}], {"fruit__iexact": "Apple"}, QueryList([{"fruit": "apple", "banana": object()}]), - ], - [ + ), + ( [{"fruit": "apple", "banana": object()}], {"fruit__iexact": "Notmatch"}, QueryList([]), - ], - [ + ), + ( [{"fruit": "apple", "banana": object()}], {"fruit": "notmatch"}, QueryList([]), - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit": "apple"}, [{"fruit": "apple"}], - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit__in": "app"}, [{"fruit": "apple"}], - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit__icontains": "App"}, [{"fruit": "apple"}], - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit__contains": "app"}, [{"fruit": "apple"}], - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit__regex": r"app.*"}, [{"fruit": "apple"}], - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit__iregex": r"App.*"}, [{"fruit": "apple"}], - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit__startswith": "a"}, [{"fruit": "apple"}], - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit__istartswith": "AP"}, [{"fruit": "apple"}], - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit__startswith": "z"}, [], - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit__endswith": "le"}, [{"fruit": "apple"}], - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit__iendswith": "LE"}, [{"fruit": "apple"}], - ], - [ + ), + ( [{"fruit": "apple"}, {"fruit": "mango"}], {"fruit__endswith": "z"}, [], - ], - [ + ), + ( [ {"fruit": "apple"}, {"fruit": "mango"}, @@ -139,8 +139,8 @@ class Obj: ], {"fruit__in": ["apple", "mango"]}, [{"fruit": "apple"}, {"fruit": "mango"}], - ], - [ + ), + ( [ {"fruit": "apple"}, {"fruit": "mango"}, @@ -149,8 +149,8 @@ class Obj: ], {"fruit__nin": ["apple", "mango"]}, [{"fruit": "banana"}, {"fruit": "kiwi"}], - ], - [ + ), + ( [ {"place": "book store", "city": "Tampa", "state": "Florida"}, {"place": "coffee shop", "city": "Tampa", "state": "Florida"}, @@ -170,8 +170,8 @@ class Obj: {"place": "book store", "city": "Tampa", "state": "Florida"}, {"place": "coffee shop", "city": "Tampa", "state": "Florida"}, ], - ], - [ + ), + ( [ {"place": "book store", "city": "Tampa", "state": "Florida"}, {"place": "coffee shop", "city": "Tampa", "state": "Florida"}, @@ -190,8 +190,8 @@ class Obj: [ {"place": "coffee shop", "city": "Tampa", "state": "Florida"}, ], - ], - [ + ), + ( [ { "place": "Largo", @@ -215,8 +215,8 @@ class Obj: "foods": {"fruit": ["banana", "orange"], "breakfast": "cereal"}, }, ], - ], - [ + ), + ( [ { "place": "Largo", @@ -240,12 +240,12 @@ class Obj: "foods": {"fruit": ["banana", "orange"], "breakfast": "cereal"}, }, ], - ], - [[1, 2, 3, 4, 5], None, QueryList([1, 2, 3, 4, 5])], - [[1, 2, 3, 4, 5], [1], QueryList([1])], - [[1, 2, 3, 4, 5], [1, 4], QueryList([1, 4])], - [[1, 2, 3, 4, 5], lambda val: val == 1, QueryList([1])], - [[1, 2, 3, 4, 5], lambda val: val == 2, QueryList([2])], + ), + ([1, 2, 3, 4, 5], None, QueryList([1, 2, 3, 4, 5])), + ([1, 2, 3, 4, 5], [1], QueryList([1])), + ([1, 2, 3, 4, 5], [1, 4], QueryList([1, 4])), + ([1, 2, 3, 4, 5], lambda val: val == 1, QueryList([1])), + ([1, 2, 3, 4, 5], lambda val: val == 2, QueryList([2])), ], ) def test_filter( diff --git a/tests/legacy_api/test_session.py b/tests/legacy_api/test_session.py index be246359e..23119468f 100644 --- a/tests/legacy_api/test_session.py +++ b/tests/legacy_api/test_session.py @@ -217,7 +217,7 @@ def test_unset_environment(session: Session) -> None: @pytest.mark.parametrize( - "session_name,raises", + ("session_name", "raises"), [("hey.period", True), ("hey:its a colon", True), ("hey moo", False)], ) def test_periods_raise_badsessionname( diff --git a/tests/legacy_api/test_version.py b/tests/legacy_api/test_version.py index d8174295a..e2805b8da 100644 --- a/tests/legacy_api/test_version.py +++ b/tests/legacy_api/test_version.py @@ -56,7 +56,6 @@ class VersionCompareFixture(t.NamedTuple): VersionCompareFixture(a="1", op=operator.lt, b="1.0.0p1", raises=False), VersionCompareFixture(a="1", op=operator.lt, b="1.0.0-openbsd", raises=False), VersionCompareFixture(a="1", op=operator.lt, b="1", raises=AssertionError), - VersionCompareFixture(a="1", op=operator.lt, b="1", raises=AssertionError), VersionCompareFixture(a="1.0.0c", op=operator.gt, b="1.0.0b", raises=False), ], ) diff --git a/tests/legacy_api/test_window.py b/tests/legacy_api/test_window.py index 811065953..344fbe45b 100644 --- a/tests/legacy_api/test_window.py +++ b/tests/legacy_api/test_window.py @@ -172,7 +172,7 @@ def test_split_percentage( if has_version("3.4"): pytest.skip( "tmux 3.4 has a split-window bug." - + " See https://github.com/tmux/tmux/pull/3840." + + " See https://github.com/tmux/tmux/pull/3840.", ) with pytest.warns(match="Deprecated in favor of size.*"): pane = window.split_window(percent=10) @@ -211,7 +211,7 @@ def test_split_window_size(session: Session) -> None: @pytest.mark.parametrize( - "window_name_before,window_name_after", + ("window_name_before", "window_name_after"), [("test", "ha ha ha fjewlkjflwef"), ("test", "hello \\ wazzup 0")], ) def test_window_rename( diff --git a/tests/test_dataclasses.py b/tests/test_dataclasses.py index 9d164a3ef..629cfc7e2 100644 --- a/tests/test_dataclasses.py +++ b/tests/test_dataclasses.py @@ -63,7 +63,8 @@ def test_pane( pane.resize_pane(adjustment_direction=ResizeAdjustmentDirection.Down, adjustment=25) pane.resize_pane( - adjustment_direction=ResizeAdjustmentDirection.Right, adjustment=25 + adjustment_direction=ResizeAdjustmentDirection.Right, + adjustment=25, ) assert old_pane_size != pane.pane_height @@ -135,7 +136,7 @@ def test_pane( assert new_pane_2.window_id == new_pane.window_id -@pytest.fixture +@pytest.fixture() def session(session: Session) -> Session: """Verify creating Session with Session.from_session_id().""" assert session.session_id is not None diff --git a/tests/test_session.py b/tests/test_session.py index aa131702e..2fb1a5cfa 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -345,14 +345,16 @@ def test_session_new_window_with_direction( assert window_initial.window_index == "2" window_before = session.new_window( - window_name="Window before", direction=WindowDirection.Before + window_name="Window before", + direction=WindowDirection.Before, ) window_initial.refresh() assert window_before.window_index == "1" assert window_initial.window_index == "3" window_after = session.new_window( - window_name="Window after", direction=WindowDirection.After + window_name="Window after", + direction=WindowDirection.After, ) window_initial.refresh() window_after.refresh() diff --git a/tests/test_version.py b/tests/test_version.py index d8174295a..e2805b8da 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -56,7 +56,6 @@ class VersionCompareFixture(t.NamedTuple): VersionCompareFixture(a="1", op=operator.lt, b="1.0.0p1", raises=False), VersionCompareFixture(a="1", op=operator.lt, b="1.0.0-openbsd", raises=False), VersionCompareFixture(a="1", op=operator.lt, b="1", raises=AssertionError), - VersionCompareFixture(a="1", op=operator.lt, b="1", raises=AssertionError), VersionCompareFixture(a="1.0.0c", op=operator.gt, b="1.0.0b", raises=False), ], ) diff --git a/tests/test_window.py b/tests/test_window.py index 80091a4b2..f755a7fcc 100644 --- a/tests/test_window.py +++ b/tests/test_window.py @@ -208,7 +208,7 @@ def test_split_size(session: Session) -> None: @pytest.mark.parametrize( - "window_name_before,window_name_after", + ("window_name_before", "window_name_after"), [("test", "ha ha ha fjewlkjflwef"), ("test", "hello \\ wazzup 0")], ) def test_window_rename( @@ -506,7 +506,7 @@ def test_resize( adjustment=window_height_adjustment * 2, ) assert window_height_before + (window_height_adjustment * 2) == int( - window.window_height + window.window_height, ) # Adjustment: Up @@ -557,14 +557,16 @@ def test_new_window_with_direction( assert window_initial.window_index == "2" window_before = window_initial.new_window( - window_name="Window before", direction=WindowDirection.Before + window_name="Window before", + direction=WindowDirection.Before, ) window_initial.refresh() assert window_before.window_index == "2" assert window_initial.window_index == "3" window_after = window_initial.new_window( - window_name="Window after", direction=WindowDirection.After + window_name="Window after", + direction=WindowDirection.After, ) window_initial.refresh() window_after.refresh() From e797cab9bc80c5ccb393412e0ad5ba9a6e3ef4a1 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 24 Mar 2024 12:03:49 -0500 Subject: [PATCH 2/3] chore(query_list): Preserve output of original errors via `logging` --- src/libtmux/_internal/query_list.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libtmux/_internal/query_list.py b/src/libtmux/_internal/query_list.py index 997436b28..073fb0191 100644 --- a/src/libtmux/_internal/query_list.py +++ b/src/libtmux/_internal/query_list.py @@ -5,11 +5,14 @@ This is an internal API not covered by versioning policy. """ +import logging import re import traceback import typing as t from collections.abc import Iterable, Mapping, Sequence +logger = logging.getLogger(__name__) + if t.TYPE_CHECKING: class LookupProtocol(t.Protocol): @@ -100,8 +103,9 @@ def keygetter( elif hasattr(dct, sub_field): dct = getattr(dct, sub_field) - except Exception: + except Exception as e: traceback.print_stack() + logger.debug(f"The above error was {e}") return None return dct @@ -140,8 +144,9 @@ def parse_lookup( field_name = path.rsplit(lookup)[0] if field_name is not None: return keygetter(obj, field_name) - except Exception: + except Exception as e: traceback.print_stack() + logger.debug(f"The above error was {e}") return None From dcc8cb2d1a36e7b31aa7057f564c5656abb58f14 Mon Sep 17 00:00:00 2001 From: Tony Narlock Date: Sun, 24 Mar 2024 11:49:51 -0500 Subject: [PATCH 3/3] docs(CHANGES): Note ruff automated fixes --- CHANGES | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGES b/CHANGES index 5184692bd..007fa65aa 100644 --- a/CHANGES +++ b/CHANGES @@ -15,6 +15,25 @@ $ pip install --user --upgrade --pre libtmux +### Development + +- Aggressive automated lint fixes via `ruff` (#539) + + via ruff v0.3.4, all automated lint fixes, including unsafe and previews were applied: + + ```sh + ruff check --select ALL . --fix --unsafe-fixes --preview --show-fixes; ruff format . + ``` + + Branches were treated with: + + ```sh + git rebase \ + --strategy-option=theirs \ + --exec 'poetry run ruff check --select ALL . --fix --unsafe-fixes --preview --show-fixes; poetry run ruff format .; git add src tests; git commit --amend --no-edit' \ + origin/master + ``` + ## libtmux 0.35.1 (2024-03-23) ### Bug fix