Skip to content

Commit bbfee75

Browse files
authored
fix(tmux_cmd): use shutil.which and only PATH to discover tmux (#407)
shutil.which() has been available since python 3.3 See also: https://docs.python.org/3/library/shutil.html#shutil.which
2 parents fbddbc6 + 7643b43 commit bbfee75

File tree

4 files changed

+10
-98
lines changed

4 files changed

+10
-98
lines changed

CHANGES

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ $ pip install --user --upgrade --pre libtmux
1414

1515
### Breaking changes
1616

17+
- Remove `common.which()` in favor of {func}`shutil.which`, Credit:
18+
@rocksandska, via #407
1719
- Fixes #402: {func}`common.tmux_cmd` will only strip _trailing_ empty lines. Before this change,
1820
all empty lines were filtered out. This will lead to a more accurate behavior when using
1921
{meth}`Pane.capture_pane`. Credit: @rockandska, via #405.

libtmux/common.py

+3-84
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import logging
99
import os
1010
import re
11+
import shutil
1112
import subprocess
1213
import sys
1314
import typing as t
@@ -203,14 +204,6 @@ class tmux_cmd:
203204
"""
204205
:term:`tmux(1)` command via :py:mod:`subprocess`.
205206
206-
Parameters
207-
----------
208-
tmux_search_paths : list, optional
209-
Default PATHs to search tmux for, defaults to ``default_paths`` used
210-
in :func:`which`.
211-
append_env_path : bool
212-
Append environment PATHs to tmux search paths. True by default.
213-
214207
Examples
215208
--------
216209
@@ -239,14 +232,7 @@ class tmux_cmd:
239232
"""
240233

241234
def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
242-
tmux_bin = which(
243-
"tmux",
244-
default_paths=kwargs.get(
245-
"tmux_search_paths",
246-
["/bin", "/sbin", "/usr/bin", "/usr/sbin", "/usr/local/bin"],
247-
),
248-
append_env_path=kwargs.get("append_env_path", True),
249-
)
235+
tmux_bin = shutil.which("tmux")
250236
if not tmux_bin:
251237
raise (exc.TmuxCommandNotFound)
252238

@@ -461,73 +447,6 @@ def get_by_id(self, id: str) -> Optional[O]:
461447
return None
462448

463449

464-
def which(
465-
exe: str,
466-
default_paths: t.List[str] = [
467-
"/bin",
468-
"/sbin",
469-
"/usr/bin",
470-
"/usr/sbin",
471-
"/usr/local/bin",
472-
],
473-
append_env_path: bool = True,
474-
) -> t.Optional[str]:
475-
"""
476-
Return path of bin. Python clone of /usr/bin/which.
477-
478-
Parameters
479-
----------
480-
exe : str
481-
Application to search PATHs for.
482-
default_paths : list
483-
Paths to check inside of
484-
append_env_path : bool, optional
485-
Append list of directories to check in from PATH environment variable.
486-
Default True. Setting False only for testing / diagnosing.
487-
488-
Returns
489-
-------
490-
str
491-
path of application, if found in paths.
492-
493-
Notes
494-
-----
495-
from salt.util - https://www.github.com/saltstack/salt - license apache
496-
"""
497-
498-
def _is_executable_file_or_link(exe: str) -> bool:
499-
# check for os.X_OK doesn't suffice because directory may executable
500-
return os.access(exe, os.X_OK) and (os.path.isfile(exe) or os.path.islink(exe))
501-
502-
if _is_executable_file_or_link(exe):
503-
# executable in cwd or fullpath
504-
return exe
505-
506-
# Enhance POSIX path for the reliability at some environments, when
507-
# $PATH is changing. This also keeps order, where 'first came, first
508-
# win' for cases to find optional alternatives
509-
if append_env_path:
510-
search_path = (
511-
os.environ.get("PATH") and os.environ["PATH"].split(os.pathsep) or list()
512-
)
513-
else:
514-
search_path = []
515-
516-
for default_path in default_paths:
517-
if default_path not in search_path:
518-
search_path.append(default_path)
519-
for path in search_path:
520-
full_path = os.path.join(path, exe)
521-
if _is_executable_file_or_link(full_path):
522-
return full_path
523-
logger.info(
524-
"'{}' could not be found in the following search path: "
525-
"'{}'".format(exe, search_path)
526-
)
527-
528-
return None
529-
530-
531450
def get_version() -> LooseVersion:
532451
"""
533452
Return tmux version.
@@ -541,7 +460,7 @@ def get_version() -> LooseVersion:
541460
Returns
542461
-------
543462
:class:`distutils.version.LooseVersion`
544-
tmux version according to :func:`libtmux.common.which`'s tmux
463+
tmux version according to :func:`shtuil.which`'s tmux
545464
"""
546465
proc = tmux_cmd("-V")
547466
if proc.stderr:

libtmux/conftest.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22
import os
33
import typing as t
4+
import shutil
45

56
import pytest
67

@@ -9,7 +10,6 @@
910
from _pytest.monkeypatch import MonkeyPatch
1011

1112
from libtmux import exc
12-
from libtmux.common import which
1313
from libtmux.server import Server
1414
from libtmux.test import TEST_SESSION_PREFIX, get_test_session_name, namer
1515

@@ -109,7 +109,7 @@ def add_doctest_fixtures(
109109
request: SubRequest,
110110
doctest_namespace: t.Dict[str, t.Any],
111111
) -> None:
112-
if isinstance(request._pyfuncitem, DoctestItem) and which("tmux"):
112+
if isinstance(request._pyfuncitem, DoctestItem) and shutil.which("tmux"):
113113
doctest_namespace["server"] = request.getfixturevalue("server")
114114
session: "Session" = request.getfixturevalue("session")
115115
doctest_namespace["session"] = session

tests/test_common.py

+3-12
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
has_version,
2525
session_check_name,
2626
tmux_cmd,
27-
which,
2827
)
2928
from libtmux.exc import BadSessionName, LibTmuxException, TmuxCommandNotFound
3029
from libtmux.session import Session
@@ -174,18 +173,10 @@ def test_has_lte_version() -> None:
174173
assert not has_lte_version("1.7b")
175174

176175

177-
def test_which_no_bin_found() -> None:
178-
assert which("top")
179-
assert which("top", default_paths=[])
180-
assert not which("top", default_paths=[], append_env_path=False)
181-
assert not which("top", default_paths=["/"], append_env_path=False)
182-
183-
184-
def test_tmux_cmd_raises_on_not_found() -> None:
176+
def test_tmux_cmd_raises_on_not_found(monkeypatch: pytest.MonkeyPatch) -> None:
177+
monkeypatch.setenv("PATH", "")
185178
with pytest.raises(TmuxCommandNotFound):
186-
tmux_cmd("-V", tmux_search_paths=[], append_env_path=False)
187-
188-
tmux_cmd("-V")
179+
tmux_cmd("-V")
189180

190181

191182
def test_tmux_cmd_unicode(session: Session) -> None:

0 commit comments

Comments
 (0)