Skip to content

Commit b48725e

Browse files
committed
refactor: Convert common_async.py code blocks to executable doctests
Replace :: code blocks with >>> executable doctests using CPython pattern. All examples now use asyncio.run() and assert behavior (True/False) rather than exact values. Uses fixtures from conftest (server, asyncio, tmux_cmd_async) for proper TestServer isolation. Changes: - Module docstring: 3 executable examples (Pattern A, B, Performance) - tmux_cmd_async class: 3 executable examples (basic, concurrent, error handling) - get_version function: 2 executable examples (basic, concurrent) - Total: 8 executable doctests (0 SKIPs) Follows CPython asyncio doctest patterns from ~/study/c/cpython/notes/asyncio-doctest.md Verified with: pytest src/libtmux/common_async.py --doctest-modules -v Result: 3 passed in 0.29s
1 parent 6b56e9f commit b48725e

File tree

1 file changed

+77
-103
lines changed

1 file changed

+77
-103
lines changed

src/libtmux/common_async.py

Lines changed: 77 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -11,52 +11,44 @@
1111
1212
libtmux provides two complementary async patterns:
1313
14-
**Pattern A**: `.acmd()` methods on Server/Session/Window/Pane objects::
14+
**Pattern A**: `.acmd()` methods on Server/Session/Window/Pane objects:
1515
16-
import asyncio
17-
import libtmux
16+
>>> import asyncio
17+
>>> async def example():
18+
... # Uses 'server' fixture from conftest
19+
... result = await server.acmd('list-sessions')
20+
... return isinstance(result.stdout, list)
21+
>>> asyncio.run(example())
22+
True
1823
19-
async def example():
20-
server = libtmux.Server()
21-
result = await server.acmd('list-sessions')
22-
return result.stdout
24+
**Pattern B**: Direct async execution with `tmux_cmd_async()`:
2325
24-
asyncio.run(example())
25-
# Returns: [...]
26-
27-
**Pattern B**: Direct async execution with `tmux_cmd_async()`::
28-
29-
import asyncio
30-
from libtmux.common_async import tmux_cmd_async
31-
32-
async def example():
33-
result = await tmux_cmd_async('list-sessions')
34-
return result.stdout
35-
36-
asyncio.run(example())
37-
# Returns: [...]
26+
>>> async def example_b():
27+
... # Uses test server socket for isolation
28+
... result = await tmux_cmd_async('-L', server.socket_name, 'list-sessions')
29+
... return isinstance(result.stdout, list)
30+
>>> asyncio.run(example_b())
31+
True
3832
3933
Both patterns preserve 100% of the synchronous API. See the quickstart guide
4034
for more information: https://libtmux.git-pull.com/quickstart_async.html
4135
4236
Performance
4337
-----------
4438
45-
Async provides significant performance benefits for concurrent operations::
46-
47-
import asyncio
48-
from libtmux.common_async import tmux_cmd_async
39+
Async provides significant performance benefits for concurrent operations:
4940
50-
async def concurrent():
51-
# 2-3x faster than sequential execution
52-
results = await asyncio.gather(
53-
tmux_cmd_async('list-sessions'),
54-
tmux_cmd_async('list-windows'),
55-
tmux_cmd_async('list-panes'),
56-
)
57-
return results
58-
59-
asyncio.run(concurrent())
41+
>>> async def concurrent():
42+
... # 2-3x faster than sequential execution
43+
... sock = server.socket_name
44+
... results = await asyncio.gather(
45+
... tmux_cmd_async('-L', sock, 'list-sessions'),
46+
... tmux_cmd_async('-L', sock, 'list-windows', '-a'),
47+
... tmux_cmd_async('-L', sock, 'list-panes', '-a'),
48+
... )
49+
... return len(results) == 3
50+
>>> asyncio.run(concurrent())
51+
True
6052
6153
See Also
6254
--------
@@ -260,48 +252,37 @@ class tmux_cmd_async:
260252
--------
261253
**Basic Usage**: Execute a single tmux command asynchronously:
262254
263-
>>> import asyncio
264-
>>> async def main():
265-
... proc = await tmux_cmd_async(f'-L{server.socket_name}', 'new-session', '-d', '-P', '-F#S')
266-
... if proc.stderr:
267-
... raise exc.LibTmuxException(
268-
... 'Command: %s returned error: %s' % (proc.cmd, proc.stderr)
269-
... )
270-
... print(f'tmux command returned {" ".join(proc.stdout)}')
271-
>>> asyncio.run(main())
272-
tmux command returned 2
273-
274-
**Concurrent Operations**: Execute multiple commands in parallel for 2-3x speedup::
275-
276-
import asyncio
277-
from libtmux.common_async import tmux_cmd_async
278-
279-
async def concurrent_example():
280-
# All commands run concurrently
281-
results = await asyncio.gather(
282-
tmux_cmd_async('list-sessions'),
283-
tmux_cmd_async('list-windows'),
284-
tmux_cmd_async('list-panes'),
285-
)
286-
return [len(r.stdout) for r in results]
287-
288-
asyncio.run(concurrent_example())
289-
# Returns: [...]
290-
291-
**Error Handling**: Check return codes and stderr::
292-
293-
import asyncio
294-
from libtmux.common_async import tmux_cmd_async
295-
296-
async def check_session():
297-
result = await tmux_cmd_async('has-session', '-t', 'my_session')
298-
if result.returncode != 0:
299-
print("Session doesn't exist")
300-
return False
301-
return True
302-
303-
asyncio.run(check_session())
304-
# Returns: False
255+
>>> async def basic_example():
256+
... # Execute command with isolated socket
257+
... proc = await tmux_cmd_async('-L', server.socket_name, 'new-session', '-d', '-P', '-F#S')
258+
... # Verify command executed successfully
259+
... return len(proc.stdout) > 0 and not proc.stderr
260+
>>> asyncio.run(basic_example())
261+
True
262+
263+
**Concurrent Operations**: Execute multiple commands in parallel for 2-3x speedup:
264+
265+
>>> async def concurrent_example():
266+
... # All commands run concurrently
267+
... sock = server.socket_name
268+
... results = await asyncio.gather(
269+
... tmux_cmd_async('-L', sock, 'list-sessions'),
270+
... tmux_cmd_async('-L', sock, 'list-windows', '-a'),
271+
... tmux_cmd_async('-L', sock, 'list-panes', '-a'),
272+
... )
273+
... return all(isinstance(r.stdout, list) for r in results)
274+
>>> asyncio.run(concurrent_example())
275+
True
276+
277+
**Error Handling**: Check return codes and stderr:
278+
279+
>>> async def check_session():
280+
... # Non-existent session returns non-zero returncode
281+
... sock = server.socket_name
282+
... result = await tmux_cmd_async('-L', sock, 'has-session', '-t', 'nonexistent_12345')
283+
... return result.returncode != 0
284+
>>> asyncio.run(check_session())
285+
True
305286
306287
Equivalent to:
307288
@@ -425,32 +406,25 @@ async def get_version() -> LooseVersion:
425406
426407
Examples
427408
--------
428-
Get tmux version asynchronously::
429-
430-
import asyncio
431-
from libtmux.common_async import get_version
432-
433-
async def check_version():
434-
version = await get_version()
435-
print(f"tmux version: {version}")
436-
437-
asyncio.run(check_version())
438-
# Prints: tmux version: 3.4
439-
440-
Use in concurrent operations::
441-
442-
import asyncio
443-
from libtmux.common_async import get_version, tmux_cmd_async
444-
445-
async def check_all():
446-
version, sessions = await asyncio.gather(
447-
get_version(),
448-
tmux_cmd_async('list-sessions'),
449-
)
450-
return version, len(sessions.stdout)
451-
452-
asyncio.run(check_all())
453-
# Returns: (LooseVersion('3.4'), 2)
409+
Get tmux version asynchronously:
410+
411+
>>> async def check_version():
412+
... version = await get_version()
413+
... return len(str(version)) > 0
414+
>>> asyncio.run(check_version())
415+
True
416+
417+
Use in concurrent operations:
418+
419+
>>> async def check_all():
420+
... sock = server.socket_name
421+
... version, sessions = await asyncio.gather(
422+
... get_version(),
423+
... tmux_cmd_async('-L', sock, 'list-sessions'),
424+
... )
425+
... return isinstance(str(version), str) and isinstance(sessions.stdout, list)
426+
>>> asyncio.run(check_all())
427+
True
454428
455429
Returns
456430
-------

0 commit comments

Comments
 (0)