You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We need a way to snapshot a state, including pane contents and the full object graph, for use in debug outputs.
Problem: We need the most recent state at the time of WaitTimeout, as things may shift after the timeout, including the pane, window, session, and even server itself being active. Sometimes these errors can manifest remotely in CI pipelines.
Waiter v3.0:
WaitTimeout and WaitResult needs to include a snapshot
This proposal extends libtmux’s Waiter functionality so that when a wait operation times out, the resulting exceptions and WaitResult objects contain immutable dataclass snapshots of tmux objects. These snapshots replace the old dictionary-based snapshots (e.g., self.pane_snapshot = { ... }) with more robust, typed, and maintainable dataclasses like PaneSnapshot, WindowSnapshot, etc.
1. Rationale
Improved Diagnostics: When a wait times out, having a complete, immutable record of the tmux object’s state in a well-defined dataclass makes debugging faster.
Type Safety: Dataclass snapshots ensure fields are consistently named and typed.
Maintainability: Easy to add or remove fields in one place without worrying about scattered dictionary references.
Better Test Output: With a pytest plugin (using pytest_assertrepr_compare), the wait-timeout errors can print structured snapshots automatically.
2. Snapshot Dataclasses (Vanilla Python)
Below is an example of vanilla dataclass snapshots for the four main tmux objects (Server, Session, Window, Pane). Each snapshot is immutable (frozen=True), capturing the object’s fields at a specific moment in time:
Note: Each snapshot class is read-only, forbidding tmux commands. By default, we store a created_at timestamp and optionally capture the entire parent-child hierarchy (e.g., session → windows → panes).
3. Specialized WaitTimeout Exceptions
Whenever a wait operation times out, we raise specialized exceptions (PaneWaitTimeout, WindowWaitTimeout, etc.) that embed these snapshot objects, rather than dictionaries:
# libtmux/exc.py (or a new module for wait-related exceptions)importtimefromlibtmux.excimportLibTmuxException, WaitTimeoutfromlibtmux.snapshotimport (
PaneSnapshot, WindowSnapshot, SessionSnapshot, ServerSnapshot
)
fromlibtmux._internal.waiter_typesimportWaitResultclassPaneWaitTimeout(WaitTimeout):
def__init__(self, message: str, pane, wait_result: WaitResult|None=None):
super().__init__(message, wait_result)
self.pane=pane# Build a snapshot for debuggingself.pane_snapshot=PaneSnapshot.from_pane(
pane, capture_content=notwait_resultornotwait_result.content
)
# Store the final content array for convenienceifwait_resultandwait_result.content:
self.pane_contents=wait_result.contentelse:
self.pane_contents=self.pane_snapshot.pane_content# ... Similarly for WindowWaitTimeout, SessionWaitTimeout, ServerWaitTimeout ...
When a PaneWaitTimeout is raised, code (or pytest) can inspect exc.pane_snapshot to see exactly what the pane state looked like at the moment of timeout.
4. Updating Wait Functions to Raise Specialized Exceptions
In waiter.py (or wherever your wait logic lives), replace the generic WaitTimeout with specialized versions. For example:
So when a test fails on an assertion involving a PaneWaitTimeout, pytest will show a structured snapshot of the pane.
6. Summary of Benefits
Improved Debugging: Dataclass snapshots provide a consistent, structured view of tmux objects at timeout.
Immutable States: Using frozen=True ensures the captured data remains a faithful “moment in time.”
Type Safety: Your IDE or static analyzer knows exactly what fields exist on PaneSnapshot, etc.
Centralized Logic: The from_* factory methods define how to copy fields once and for all, preventing drift across the codebase.
Better CI Diagnostics: The specialized exceptions store all relevant object details automatically, reducing guesswork in failing test logs.
By leveraging these dataclass snapshots, libtmux’s Waiter becomes far more transparent about why timeouts occur, simplifying test maintenance and debugging.
The text was updated successfully, but these errors were encountered:
Snapshot / frame dataclass #370
We need a way to snapshot a state, including pane contents and the full object graph, for use in debug outputs.
Problem: We need the most recent state at the time of
WaitTimeout
, as things may shift after the timeout, including the pane, window, session, and even server itself being active. Sometimes these errors can manifest remotely in CI pipelines.Waiter v3.0:
WaitTimeout
andWaitResult
needs to include a snapshotpytest_assertrepr_compare
: docs, sourceassertrepr_compare
Waiter 3.0
Enhanced Waiter Proposal With Dataclass Snapshots
This proposal extends libtmux’s Waiter functionality so that when a wait operation times out, the resulting exceptions and
WaitResult
objects contain immutable dataclass snapshots of tmux objects. These snapshots replace the old dictionary-based snapshots (e.g.,self.pane_snapshot = { ... }
) with more robust, typed, and maintainable dataclasses likePaneSnapshot
,WindowSnapshot
, etc.1. Rationale
pytest_assertrepr_compare
), the wait-timeout errors can print structured snapshots automatically.2. Snapshot Dataclasses (Vanilla Python)
Below is an example of vanilla dataclass snapshots for the four main tmux objects (
Server
,Session
,Window
,Pane
). Each snapshot is immutable (frozen=True
), capturing the object’s fields at a specific moment in time:Note: Each snapshot class is read-only, forbidding tmux commands. By default, we store a
created_at
timestamp and optionally capture the entire parent-child hierarchy (e.g., session → windows → panes).3. Specialized
WaitTimeout
ExceptionsWhenever a wait operation times out, we raise specialized exceptions (
PaneWaitTimeout
,WindowWaitTimeout
, etc.) that embed these snapshot objects, rather than dictionaries:When a
PaneWaitTimeout
is raised, code (or pytest) can inspectexc.pane_snapshot
to see exactly what the pane state looked like at the moment of timeout.4. Updating Wait Functions to Raise Specialized Exceptions
In
waiter.py
(or wherever your wait logic lives), replace the genericWaitTimeout
with specialized versions. For example:Likewise for functions like
wait_for_session_condition
, raise aSessionWaitTimeout
; forwait_for_window_condition
, aWindowWaitTimeout
; and so on.5. pytest Integration (Optional)
Finally, you can define a
pytest_assertrepr_compare
hook that prints these snapshots in a user-friendly manner:So when a test fails on an assertion involving a
PaneWaitTimeout
, pytest will show a structured snapshot of the pane.6. Summary of Benefits
frozen=True
ensures the captured data remains a faithful “moment in time.”PaneSnapshot
, etc.from_*
factory methods define how to copy fields once and for all, preventing drift across the codebase.By leveraging these dataclass snapshots, libtmux’s Waiter becomes far more transparent about why timeouts occur, simplifying test maintenance and debugging.
The text was updated successfully, but these errors were encountered: