Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
43696b2
chore: Add `__init__.py` for tests/examples
tony Feb 27, 2025
3116d30
chore: Add `__init__.py` for tests/examples/test
tony Feb 26, 2025
86895e7
chore: Add `__init__.py` for tests/examples/_internal/waiter
tony Feb 27, 2025
a0e5f1e
fix(retry): Improve retry_until_extended function with better error m…
tony Feb 26, 2025
14216ff
feat(waiter): Enhance terminal content waiting utility with fluent AP…
tony Feb 26, 2025
955e7dc
test(waiter): Fix test cases and improve type safety
tony Feb 26, 2025
17be03a
docs(waiter): Add comprehensive documentation for terminal content wa…
tony Feb 26, 2025
a48689a
pyproject(mypy[exceptions]): examples to ignore `no-untyped-def`
tony Feb 26, 2025
b093ec1
test: add conftest.py to register example marker
tony Feb 26, 2025
d61e766
refactor(tests[waiter]): Add waiter test examples into individual files
tony Feb 26, 2025
454c8eb
docs(CHANGES) Note `Waiter`
tony Feb 27, 2025
fc24199
feat!(Window): Set option flags
tony Feb 5, 2024
e4c6a7f
refactor!(Window): Deprecate set_window_option -> set_option
tony Feb 5, 2024
57d3ff5
tests(Window): Rename test for show_window_options()
tony Feb 6, 2024
b81c429
tests(Window): set_option
tony Feb 6, 2024
b7c3d18
Window: Add show_option(), deprecate show_window_option()
tony Feb 6, 2024
df85ff1
chore(Window): {set,show}-window-option -> {set,show}-option -w
tony Feb 6, 2024
485a88b
libtmux.constants: Add OptionScope and OPTION_SCOPE_FLAG_MAP
tony Feb 6, 2024
7fd866e
feat(Window): scope param for Window.{set,show}_option
tony Feb 6, 2024
0330bc4
tests(Window): show_options w/ scope
tony Feb 6, 2024
f284c56
tests: show_window_option() -> show_option()
tony Feb 6, 2024
74d74ac
feat(common): Add CmdMixin, CmdProtocol
tony Feb 8, 2024
ce45598
refactor!(options): Move handle_options_error -> options
tony Feb 8, 2024
3586301
feat(internal[sparse_array]): Add SparseArray
tony Jun 20, 2024
94dfdfd
feat(options): Add OptionsMixin
tony Feb 8, 2024
e19465b
feat(Window): Use OptionsMixin for Window.set_option, Window.show_opt…
tony Feb 7, 2024
44fa187
feat(Pane): Use OptionsMixin for Pane.set_option, Pane.show_option(s)
tony Feb 5, 2024
3bad105
feat(Session): Use OptionsMixin for Session.set_option, Session.show_…
tony Feb 7, 2024
f2a75a2
feat(Server): Use OptionsMixin for Server.set_option, Server.show_opt…
tony Feb 8, 2024
bfdd04c
tests: Handle Window.show_options scope mismatch
tony Feb 7, 2024
c0485ae
tests(window): Version guard to scope
tony Feb 6, 2024
0751312
tests(Window): For Window.default_option_scope
tony Feb 8, 2024
ebec36f
docs(options): Add page for option helpers
tony Feb 8, 2024
27fec10
internal(constants[options]): GPT generated dataclasses
tony Feb 9, 2024
4afa370
tests(test_options): Test OptionsMixin
tony Feb 8, 2024
e881185
docs(CHANGES): Note updates for options
tony Feb 6, 2024
55b2ce7
constants: Add HOOK_SCOPE_FLAG_MAP
tony Feb 16, 2024
d890c3d
docs(API): Document internal constants
tony Feb 15, 2024
6513cfd
feat(internal[constants]): Add Hooks data structure
tony Feb 15, 2024
2e6b985
feat!(hooks): HooksMixin
tony Feb 15, 2024
eca0124
feat(Pane): Add HooksMixin
tony Feb 15, 2024
a5eac7b
feat(Window): Add HooksMixin
tony Feb 15, 2024
c4bab53
feat(Session): Add HooksMixin
tony Feb 15, 2024
adf4523
feat(Server): Add HooksMixin
tony Feb 15, 2024
876ac15
docs(API): Add Hooks
tony Feb 16, 2024
b319771
tests(test_hooks): Test HooksMixin
tony Feb 15, 2024
4aada03
!squash tests(test_options): Tests for OptionsMixin
tony Apr 13, 2024
4bbbba6
!squash test_options: renamings
tony May 5, 2024
a5b3315
!squash tmux set options. I want to be able to pass in high-level, "…
tony May 5, 2024
8ec5712
Revert "!squash tmux set options. I want to be able to pass in high-…
tony Jun 20, 2024
1cde41e
!squash test_options: Stable baseline
tony Jun 20, 2024
3a71304
!squash to feat(Window): scope param for Window.{set,show}_option
tony Jul 20, 2024
f0a960a
fix(options): improve type safety for SparseArray handling
tony Feb 23, 2025
b607d85
test(options): update terminal-features test for tmux 3.4
tony Feb 23, 2025
6fe5e3b
test(options): improve test coverage and type safety
tony Feb 23, 2025
54e9e05
fix(tests): improve type safety in style option tests
tony Feb 23, 2025
230a19c
fix(tests): handle status-format version compatibility
tony Feb 23, 2025
1bc4f05
fix(tests): handle update-environment version compatibility
tony Feb 23, 2025
dd0438b
fix(options): remove redundant cast in _show_option
tony Oct 25, 2025
86c1a90
fix(compat): add tmux version compatibility for 3.2a-3.5
tony Oct 25, 2025
6d1b4f6
ci: set fail-fast false for test matrix
tony Oct 25, 2025
b939e66
fix(tests): handle tmux version differences in options tests
tony Oct 25, 2025
48c7b3a
fix(tests): handle style option format changes in tmux 3.2
tony Oct 25, 2025
1a579e2
fix(tests): handle bold→bright conversion in complex style test
tony Oct 25, 2025
0145e78
fix(tests): skip format expansion test on tmux <3.2
tony Oct 25, 2025
42add28
fix(tests): add delay after send_keys in waiter test
tony Oct 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ jobs:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ['3.9', '3.13']
tmux-version: ['2.6', '2.7', '2.8', '3.0a', '3.1b', '3.2a', '3.3a', '3.4', '3.5', 'master']
Expand Down
64 changes: 51 additions & 13 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ $ pip install --user --upgrade --pre libtmux

- _Future release notes will be placed here_

### New features

#### Waiting (#582)

Added experimental `waiter.py` module for polling for terminal content in tmux panes:

- Fluent API inspired by Playwright for better readability and chainable options
- Support for multiple pattern types (exact text, contains, regex, custom predicates)
- Composable waiting conditions with `wait_for_any_content` and `wait_for_all_content`
- Enhanced error handling with detailed timeouts and match information
- Robust shell prompt detection

## libtmux 0.46.2 (2025-05-26)

### Development
Expand All @@ -33,8 +45,8 @@ $ pip install --user --upgrade --pre libtmux

_Maintenance only, no bug fixes or new features_

A version branch has been created at v0.46.x, the next release of v0.47.0 may
be a few months in waiting (watchers / snapshots are in development in #587).
A version branch has been created at v0.46.x, the next release of v0.47.0 may
be a few months in waiting (watchers / snapshots are in development in #587).

### Documentation

Expand Down Expand Up @@ -221,6 +233,43 @@ Add `TestServer` pytest fixture for creating temporary tmux servers (#565):
- dev dependencies: Include `typing-extensions` for Python version < 3.11 via
the `testing` and `lint` groups, via #564.

### Renamed commands

- Renamed `Window.set_window_option()` to {meth}`Window.set_option()` (#516)

Deprecated `Window.set_window_option()`

- Renamed `Window.show_window_option()` to {meth}`Window.show_option()` (#516)

Deprecated `Window.show_window_option()`

- Renamed `Window.show_window_options()` to {meth}`Window.show_options()` (#516)

Deprecated `Window.show_window_options()`

### Improved options

- Option support expanded to server, session, window, and pane
- Option support enhanced and streamlined via {class}`options.OptionsMixin`.

- `set_option`
- `show_option`
- `show_options`
- `unset_option`

- {meth}`Window.set_option()` (#516)

Added arguments:

- `format` -> `-F`
- `unset` -> `-u`
- `global` -> `-g`
- `unset_panes` -> `-U`: Also unset other panse in windows
- `prevent_overwrite`: `-o`
- `suppress_warnings`: `-q`
- `append`: `-a`


## libtmux 0.42.0 (2025-02-02)

### Bug fixes
Expand All @@ -247,17 +296,6 @@ Add `TestServer` pytest fixture for creating temporary tmux servers (#565):
- `Server`: Fix `colors` docstring to note it accepts `88` or `256`, Thank you
@TravisDart! (via #544)

### Development

#### chore: Implement PEP 563 deferred annotation resolution (#555)

- Add `from __future__ import annotations` to defer annotation resolution and reduce unnecessary runtime computations during type checking.
- Enable Ruff checks for PEP-compliant annotations:
- [non-pep585-annotation (UP006)](https://docs.astral.sh/ruff/rules/non-pep585-annotation/)
- [non-pep604-annotation (UP007)](https://docs.astral.sh/ruff/rules/non-pep604-annotation/)

For more details on PEP 563, see: https://peps.python.org/pep-0563/

## libtmux 0.40.1 (2024-12-24)

### Bug fix
Expand Down
6 changes: 6 additions & 0 deletions docs/api/hooks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Hooks

```{eval-rst}
.. automodule:: libtmux.hooks
:members:
```
2 changes: 2 additions & 0 deletions docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ servers
sessions
windows
panes
options
hooks
constants
common
exceptions
Expand Down
6 changes: 6 additions & 0 deletions docs/api/options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Options

```{eval-rst}
.. automodule:: libtmux.options
:members:
```
15 changes: 15 additions & 0 deletions docs/internals/constants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Internal Constants - `libtmux._internal.constants`

:::{warning}
Be careful with these! These constants are private, internal as they're **not** covered by version policies. They can break or be removed between minor versions!

If you need a data structure here made public or stabilized please [file an issue](https://github.com/tmux-python/libtmux/issues).
:::

```{eval-rst}
.. automodule:: libtmux._internal.constants
:members:
:undoc-members:
:inherited-members:
:show-inheritance:
```
2 changes: 2 additions & 0 deletions docs/internals/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ If you need an internal API stabilized please [file an issue](https://github.com
```{toctree}
dataclasses
query_list
waiter
constants
```

## Environmental variables
Expand Down
135 changes: 135 additions & 0 deletions docs/internals/waiter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
(waiter)=

# Waiters - `libtmux._internal.waiter`

The waiter module provides utilities for waiting on specific content to appear in tmux panes, making it easier to write reliable tests that interact with terminal output.

## Key Features

- **Fluent API**: Playwright-inspired chainable API for expressive, readable test code
- **Multiple Match Types**: Wait for exact matches, substring matches, regex patterns, or custom predicate functions
- **Composable Waiting**: Wait for any of multiple conditions or all conditions to be met
- **Flexible Timeout Handling**: Configure timeout behavior and error handling to suit your needs
- **Shell Prompt Detection**: Easily wait for shell readiness with built-in prompt detection
- **Robust Error Handling**: Improved exception handling and result reporting
- **Clean Code**: Well-formatted, linted code with proper type annotations

## Basic Concepts

When writing tests that interact with tmux sessions and panes, it's often necessary to wait for specific content to appear before proceeding with the next step. The waiter module provides a set of functions to help with this.

There are multiple ways to match content:
- **Exact match**: The content exactly matches the specified string
- **Contains**: The content contains the specified string
- **Regex**: The content matches the specified regular expression
- **Predicate**: A custom function that takes the pane content and returns a boolean

## Quick Start Examples

### Simple Waiting

Wait for specific text to appear in a pane:

```{literalinclude} ../../tests/examples/_internal/waiter/test_wait_for_text.py
:language: python
```

### Advanced Matching

Use regex patterns or custom predicates for more complex matching:

```{literalinclude} ../../tests/examples/_internal/waiter/test_wait_for_regex.py
:language: python
```

```{literalinclude} ../../tests/examples/_internal/waiter/test_custom_predicate.py
:language: python
```

### Timeout Handling

Control how long to wait and what happens when a timeout occurs:

```{literalinclude} ../../tests/examples/_internal/waiter/test_timeout_handling.py
:language: python
```

### Waiting for Shell Readiness

A common use case is waiting for a shell prompt to appear, indicating the command has completed. The example below uses a regular expression to match common shell prompt characters (`$`, `%`, `>`, `#`):

```{literalinclude} ../../tests/examples/_internal/waiter/test_wait_until_ready.py
:language: python
```

> Note: This test is skipped in CI environments due to timing issues but works well for local development.

## Fluent API (Playwright-inspired)

For a more expressive and chainable API, you can use the fluent interface provided by the `PaneContentWaiter` class:

```{literalinclude} ../../tests/examples/_internal/waiter/test_fluent_basic.py
:language: python
```

```{literalinclude} ../../tests/examples/_internal/waiter/test_fluent_chaining.py
:language: python
```

## Multiple Conditions

The waiter module also supports waiting for multiple conditions at once:

```{literalinclude} ../../tests/examples/_internal/waiter/test_wait_for_any_content.py
:language: python
```

```{literalinclude} ../../tests/examples/_internal/waiter/test_wait_for_all_content.py
:language: python
```

```{literalinclude} ../../tests/examples/_internal/waiter/test_mixed_pattern_types.py
:language: python
```

## Implementation Notes

### Error Handling

The waiting functions are designed to be robust and handle timing and error conditions gracefully:

- All wait functions properly calculate elapsed time for performance tracking
- Functions handle exceptions consistently and provide clear error messages
- Proper handling of return values ensures consistent behavior whether or not raises=True

### Type Safety

The waiter module is fully type-annotated to ensure compatibility with static type checkers:

- All functions include proper type hints for parameters and return values
- The ContentMatchType enum ensures that only valid match types are used
- Combined with runtime checks, this prevents type-related errors during testing

### Example Usage in Documentation

All examples in this documentation are actual test files from the libtmux test suite. The examples are included using `literalinclude` directives, ensuring that the documentation remains synchronized with the actual code.

## API Reference

```{eval-rst}
.. automodule:: libtmux._internal.waiter
:members:
:undoc-members:
:show-inheritance:
:member-order: bysource
```

## Extended Retry Functionality

```{eval-rst}
.. automodule:: libtmux.test.retry_extended
:members:
:undoc-members:
:show-inheritance:
:member-order: bysource
```
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ files = [
"tests",
]

[[tool.mypy.overrides]]
module = "tests.examples.*"
disallow_untyped_defs = false
disallow_incomplete_defs = false

[tool.coverage.run]
branch = true
parallel = true
Expand Down
Loading
Loading