6565import shutil
6666import sys
6767import typing as t
68+ from collections .abc import Awaitable , Generator
6869
6970from . import exc
7071from ._compat import LooseVersion
7172
7273if t .TYPE_CHECKING :
73- from collections .abc import Callable , Coroutine
74+ from collections .abc import Callable
7475
7576logger = logging .getLogger (__name__ )
7677
8889
8990
9091class AsyncEnvironmentMixin :
91- """Async mixin for manager session and server level environment variables in tmux ."""
92+ """Async mixin for managing session and server- level environment variables."""
9293
9394 _add_option = None
9495
95- acmd : Callable [[t .Any , t .Any ], Coroutine [ t . Any , t . Any , tmux_cmd_async ]]
96+ acmd : Callable [[t .Any , t .Any ], Awaitable [ tmux_cmd_async ]]
9697
9798 def __init__ (self , add_option : str | None = None ) -> None :
9899 self ._add_option = add_option
@@ -179,7 +180,8 @@ async def show_environment(self) -> dict[str, bool | str]:
179180
180181 .. versionchanged:: 0.13
181182
182- Removed per-item lookups. Use :meth:`libtmux.common_async.AsyncEnvironmentMixin.getenv`.
183+ Removed per-item lookups.
184+ Use :meth:`libtmux.common_async.AsyncEnvironmentMixin.getenv`.
183185
184186 Returns
185187 -------
@@ -242,7 +244,7 @@ async def getenv(self, name: str) -> str | bool | None:
242244 return opts_dict .get (name )
243245
244246
245- class tmux_cmd_async :
247+ class tmux_cmd_async ( Awaitable [ "tmux_cmd_async" ]) :
246248 """Run any :term:`tmux(1)` command through :py:mod:`asyncio.subprocess`.
247249
248250 This is the async-first implementation. The tmux_cmd class is auto-generated
@@ -254,7 +256,9 @@ class tmux_cmd_async:
254256
255257 >>> async def basic_example():
256258 ... # Execute command with isolated socket
257- ... proc = await tmux_cmd_async('-L', server.socket_name, 'new-session', '-d', '-P', '-F#S')
259+ ... proc = await tmux_cmd_async(
260+ ... '-L', server.socket_name, 'new-session', '-d', '-P', '-F#S'
261+ ... )
258262 ... # Verify command executed successfully
259263 ... return len(proc.stdout) > 0 and not proc.stderr
260264 >>> asyncio.run(basic_example())
@@ -279,7 +283,9 @@ class tmux_cmd_async:
279283 >>> async def check_session():
280284 ... # Non-existent session returns non-zero returncode
281285 ... sock = server.socket_name
282- ... result = await tmux_cmd_async('-L', sock, 'has-session', '-t', 'nonexistent_12345')
286+ ... result = await tmux_cmd_async(
287+ ... '-L', sock, 'has-session', '-t', 'nonexistent_12345'
288+ ... )
283289 ... return result.returncode != 0
284290 >>> asyncio.run(check_session())
285291 True
@@ -341,10 +347,10 @@ def __init__(
341347 self .returncode = returncode
342348 self ._executed = False
343349
344- async def execute (self ) -> None :
350+ async def execute (self ) -> tmux_cmd_async :
345351 """Execute the tmux command asynchronously."""
346352 if self ._executed :
347- return
353+ return self
348354
349355 try :
350356 process = await asyncio .create_subprocess_exec (
@@ -361,6 +367,15 @@ async def execute(self) -> None:
361367 raise
362368
363369 self ._executed = True
370+ return self
371+
372+ async def _run (self ) -> tmux_cmd_async :
373+ await self .execute ()
374+ return self
375+
376+ def __await__ (self ) -> Generator [t .Any , None , tmux_cmd_async ]:
377+ """Allow ``await tmux_cmd_async(...)`` to execute the command."""
378+ return self ._run ().__await__ ()
364379
365380 @property
366381 def stdout (self ) -> list [str ]:
@@ -387,12 +402,9 @@ def stderr(self) -> list[str]:
387402 stderr_split = self ._stderr .split ("\n " )
388403 return list (filter (None , stderr_split )) # filter empty values
389404
390- async def __new__ (cls , * args : t .Any , ** kwargs : t .Any ) -> tmux_cmd_async :
391- """Create and execute tmux command asynchronously."""
392- instance = object .__new__ (cls )
393- instance .__init__ (* args , ** kwargs )
394- await instance .execute ()
395- return instance
405+ def __new__ (cls , * args : t .Any , ** kwargs : t .Any ) -> tmux_cmd_async :
406+ """Create tmux command instance (execution happens when awaited)."""
407+ return super ().__new__ (cls )
396408
397409
398410async def get_version () -> LooseVersion :
0 commit comments