Skip to content

Latest commit

 

History

History
505 lines (365 loc) · 17.2 KB

File metadata and controls

505 lines (365 loc) · 17.2 KB

Migration notes

Migration and deprecation notes for libtmux are here, see {ref}changelog as well.

1. 📌 For safety, **always** pin the package
2. 📖 Check the migration notes _(You are here)_
3. 📣 If you feel something got deprecated and it interrupted you - past, present, or future - voice your opinion on the [tracker].

   We want to make libtmux fun, reliable, and useful for users.

   API changes can be painful.

   If we can do something to draw the sting, we'll do it. We're taking a balanced approach. That's why these notes are here!

   (Please pin the package. 🙏)

   [tracker]: https://github.com/tmux-python/libtmux/discussions

Complete Deprecation Reference

This table provides a quick reference for all deprecated APIs. See version-specific sections below for detailed migration examples and code samples.

Method Renamings

Class Deprecated Replacement Since Raises
Server kill_server() kill() 0.30.0 (2024-02-16) 0.51.0
Session attach_session() attach() 0.30.0 (2024-02-16) 0.51.0
Session kill_session() kill() 0.30.0 (2024-02-16) 0.51.0
Window select_window() select() 0.30.0 (2024-02-16) 0.51.0
Window kill_window() kill() 0.30.0 (2024-02-16) 0.51.0
Window split_window() split() 0.33.0 (2024-03-17) 0.51.0
Window set_window_option() set_option() 0.50.0 (2025-11-30) (warning)
Window show_window_option() show_option() 0.50.0 (2025-11-30) (warning)
Window show_window_options() show_options() 0.50.0 (2025-11-30) (warning)
Pane select_pane() select() 0.30.0 (2024-02-16) 0.51.0
Pane resize_pane() resize() 0.28.0 (2024-02-14) 0.51.0
Pane split_window() split() 0.33.0 (2024-03-17) 0.51.0

Property Renamings

Class Deprecated Replacement Since Raises
Session attached_window active_window 0.31.0 (2024-02-17) 0.51.0
Session attached_pane active_pane 0.31.0 (2024-02-17) 0.51.0
Window attached_pane active_pane 0.31.0 (2024-02-17) 0.51.0

Parameter Changes

Method(s) Deprecated Replacement Since Raises
Options/hooks methods g global_ 0.50.0 (2025-11-30) (warning)
split_window() / split() percent size 0.28.0 (2024-02-14) 0.51.0
split_window() / split() vertical/horizontal direction (PaneDirection) 0.33.0 (2024-03-17) 0.51.0
resize_pane() -U, -D, -L, -R adjustment_direction 0.28.0 (2024-02-14) 0.51.0
Server.get_by_id() id session_id 0.16.0 (2022-12-10) 0.51.0
Session.get_by_id() id window_id 0.16.0 (2022-12-10) 0.51.0
Window.get_by_id() id pane_id 0.16.0 (2022-12-10) 0.51.0

Query/Filter API Changes

Class Deprecated Replacement Since Raises
Server list_sessions() / _list_sessions() sessions property 0.17.0 (2022-12-26) 0.51.0
Server where({...}) sessions.filter(**kwargs) 0.17.0 (2022-12-26) 0.51.0
Server find_where({...}) sessions.get(default=None, **kwargs) 0.17.0 (2022-12-26) 0.51.0
Server _list_panes() / _update_panes() panes property 0.17.0 (2022-12-26) 0.51.0
Server _list_windows() / _update_windows() windows property 0.17.0 (2022-12-26) 0.51.0
Server get_by_id(id) sessions.get(session_id=..., default=None) 0.16.0 (2022-12-10) 0.51.0
Session list_windows() / _list_windows() windows property 0.17.0 (2022-12-26) 0.51.0
Session where({...}) windows.filter(**kwargs) 0.17.0 (2022-12-26) 0.51.0
Session find_where({...}) windows.get(default=None, **kwargs) 0.17.0 (2022-12-26) 0.51.0
Session get_by_id(id) windows.get(window_id=..., default=None) 0.16.0 (2022-12-10) 0.51.0
Window list_panes() / _list_panes() panes property 0.17.0 (2022-12-26) 0.51.0
Window where({...}) panes.filter(**kwargs) 0.17.0 (2022-12-26) 0.51.0
Window find_where({...}) panes.get(default=None, **kwargs) 0.17.0 (2022-12-26) 0.51.0
Window get_by_id(id) panes.get(pane_id=..., default=None) 0.16.0 (2022-12-10) 0.51.0
All children property sessions/windows/panes 0.17.0 (2022-12-26) 0.51.0

Attribute Access Changes

Pattern Deprecated Replacement Since Raises
Dict key access obj['key'] obj.key 0.17.0 (2022-12-26) 0.51.0
Dict get obj.get('key') obj.key 0.17.0 (2022-12-26) 0.51.0
Dict get w/ default obj.get('key', None) getattr(obj, 'key', None) 0.17.0 (2022-12-26) 0.51.0

Removed Items

Item Removed In Migration
tmux < 3.2a support 0.49.0 (2025-11-29) Upgrade tmux or use libtmux 0.48.x
console_to_str() 0.42.0 (2025-02-02) Use text=True in subprocess
str_from_console() 0.42.0 (2025-02-02) Use text=True in subprocess
common.which() 0.12.0 (2022-07-13) Use shutil.which()

Default Behavior Changes

Method Old Default New Default Since
Session.new_window() attach=True attach=False 0.28.0 (2024-02-14)
Window.split_window() attach=True attach=False 0.28.0 (2024-02-14)

Upcoming Release

Detailed migration steps for the next version will be posted here.

libtmux 0.57.0: Subcommand-tagged exceptions (#672)

LibTmuxException str() gains a subcommand prefix

When {exc}~libtmux.exc.LibTmuxException is raised from a libtmux method, str(exc) now starts with the originating tmux subcommand name followed by ": ". exc.args[0] still carries the original tmux error text, and the new {attr}~libtmux.exc.LibTmuxException.subcommand attribute exposes the tmux subcommand name on its own.

The error-payload type changed: exc.args[0] is now str, joined with "\n" when tmux emitted multiple stderr lines. Previously it was list[str].

Who is affected: code that pattern-matches str(exc) exactly, anchors a regex with ^ against the previous shape, or indexes exc.args[0] element-by-element expecting a list. Substring containment ("can't find" in str(exc)) and unanchored re.search patterns continue to match unchanged.

Before:

try:
    session.last_window()
except LibTmuxException as exc:
    if str(exc) == "can't find window":
        handle_missing_last_window()

After (0.57.0+) — dispatch on the typed attribute:

try:
    session.last_window()
except LibTmuxException as exc:
    if exc.subcommand == "last-window":
        handle_missing_last_window()

Or — match against the original tmux error text in exc.args[0]:

try:
    session.last_window()
except LibTmuxException as exc:
    if exc.args and exc.args[0] == "can't find window":
        handle_missing_last_window()

Client.session_id / window_id / pane_id are snapshots, not identity

{class}~libtmux.Client is new in 0.57.0, so this isn't a behavior change — but new users of {attr}~libtmux.Server.clients should know that client.session_id, client.window_id, and client.pane_id reflect the client's attached view at the moment the {class}~libtmux.Client was read. They go stale as soon as the client switches sessions, changes window, or detaches.

For typed access that reflects the client's live attachment, use {attr}~libtmux.Client.attached_session, {attr}~libtmux.Client.attached_window, and {attr}~libtmux.Client.attached_pane:

# Snapshot (may be stale)
client = server.clients.get(client_name=ctl.client_name)
session_id = client.session_id  # str captured when the object was read

# Live (re-reads list-clients; returns None if tmux no longer reports the client)
attached = client.attached_session  # libtmux.Session | None
window = client.attached_window     # libtmux.Window  | None
pane = client.attached_pane         # libtmux.Pane    | None

The client.client_name field (typically the tty path on Unix) is the client's stable identifier and does not have this caveat. The attached_* properties translate a missing list-clients row into None for convenience; direct {meth}~libtmux.Client.refresh and {meth}~libtmux.Client.from_client_name calls still raise when that client row is gone.

{attr}~libtmux.Client.attached_pane follows the attached session's current window. That can differ from the per-client active pane set by select-pane -P.

Pane.reset now uses one tmux command sequence

{meth}~libtmux.Pane.reset now bundles send-keys -R and clear-history into one tmux command sequence targeted at the pane. This closes a race where output written between separate commands could land in the scrollback that the second command then cleared.

Who is affected: test fixtures and downstream code that intercepts Pane.cmd (for example with unittest.mock.patch.object(pane, "cmd")) will no longer observe reset()'s tmux invocation. Patch Server.cmd instead, or assert on the resulting pane state directly.

Server.display_message / Window.display_message / Pane.display_message warn instead of raise

The three display_message wrappers now report tmux stderr via :func:warnings.warn rather than raising {exc}~libtmux.exc.LibTmuxException. tmux uses stderr for both genuine errors and informational messages, and the right escalation depends on tmux version and requested format; the wrappers default to warning so callers can decide. To escalate to an exception, wrap the call in :func:warnings.catch_warnings with filterwarnings("error"):

import warnings

with warnings.catch_warnings():
    warnings.filterwarnings("error", category=UserWarning)
    result = pane.display_message("#{pane_id}", get_text=True)

libtmux 0.50.0: Unified Options and Hooks API (#516)

New unified options API

All tmux objects (Server, Session, Window, Pane) now share a consistent options interface through {class}~libtmux.options.OptionsMixin:

# Get all options
session.show_options()

# Get a single option
session.show_option('base-index')

# Set an option
window.set_option('automatic-rename', True)

# Unset an option
window.unset_option('automatic-rename')

New hooks API

All tmux objects now support hook management through {class}~libtmux.hooks.HooksMixin:

# Set a hook
session.set_hook('session-renamed', 'display-message "Renamed!"')

# Get hook value
session.show_hook('session-renamed')

# Get all hooks
session.show_hooks()

# Remove a hook
session.unset_hook('session-renamed')

Deprecated Window methods

The following Window methods are deprecated and will be removed in a future release:

Deprecated Replacement
Window.set_window_option() {meth}Window.set_option() <libtmux.Window.set_option>
Window.show_window_option() {meth}Window.show_option() <libtmux.Window.show_option>
Window.show_window_options() {meth}Window.show_options() <libtmux.Window.show_options>

Before (deprecated):

window.set_window_option('automatic-rename', 'on')
window.show_window_option('automatic-rename')
window.show_window_options()

After (0.50.0+):

window.set_option('automatic-rename', True)
window.show_option('automatic-rename')
window.show_options()

Deprecated g parameter

The g parameter for global options is deprecated in favor of global_:

Before (deprecated):

session.show_option('status', g=True)
session.set_option('status', 'off', g=True)

After (0.50.0+):

session.show_option('status', global_=True)
session.set_option('status', 'off', global_=True)

Using the old g parameter will emit a {class}DeprecationWarning.

libtmux 0.46.0 (2025-02-25)

Imports removed from libtmux.test (#580)

Root-level of imports from libtmux.test are no longer possible.

# Before 0.46.0
from libtmux.test import namer
# From 0.46.0 onward
from libtmux.test.named import namer

Same thing with constants:

# Before 0.46.0
from libtmux.test import (
  RETRY_INTERVAL_SECONDS,
  RETRY_TIMEOUT_SECONDS,
  TEST_SESSION_PREFIX
)
# From 0.46.0 onward
from libtmux.test.constants import (
  RETRY_INTERVAL_SECONDS,
  RETRY_TIMEOUT_SECONDS,
  TEST_SESSION_PREFIX
)

libtmux 0.45.0 (2025-02-23)

Test helpers: Module moves

Test helper functionality has been split into focused modules (#578):

  • libtmux.test module split into:
    • libtmux.test.constants: Test-related constants (TEST_SESSION_PREFIX, etc.)
    • libtmux.test.environment: Environment variable mocking
    • libtmux.test.random: Random string generation utilities
    • libtmux.test.temporary: Temporary session/window management

Breaking: Import paths have changed. Update imports:

# Old (0.44.x and earlier)
from libtmux.test import (
    TEST_SESSION_PREFIX,
    get_test_session_name,
    get_test_window_name,
    namer,
    temp_session,
    temp_window,
    EnvironmentVarGuard,
)
# New (0.45.0+)
from libtmux.test.constants import TEST_SESSION_PREFIX
from libtmux.test.environment import EnvironmentVarGuard
from libtmux.test.random import get_test_session_name, get_test_window_name, namer
from libtmux.test.temporary import temp_session, temp_window

0.35.0: Commands require explicit targets (2024-03-17)

Commands require explicit targets (#535)

  • {meth}Server.cmd(), {meth}Session.cmd(), {meth}Window.cmd(), {meth}Pane.cmd() require passing target instead of ['-t', target], ['-tTargetName'], etc. This change is to avoid issues mistakenly interpreting -t in other shell values as targets.

    Before:

    session.cmd('send-keys', 'echo hello', '-t', '0')

    With 0.35.0 and after:

    session.cmd('send-keys', 'echo hello', target='0')

0.33.0: Deprecations for splitting (2024-03-03)

Deprecations (#532)

  • Window.split_window() to {meth}Window.split()
  • Pane.split_window() to {meth}Pane.split()

0.31.0: Renaming and command cleanup (2024-02-17)

Cleanups (#527)

  • Commands: Param change

    {meth}Server.cmd(), {meth}Session.cmd(), {meth}Window.cmd(), {meth}Pane.cmd()

    • Use cmd: str as first positional
    • Removed unused keyword arguments **kwargs

Renamings (#527)

  • Session.attached_window renamed to {meth}Session.active_window
    • Session.attached_window deprecated
  • Session.attached_pane renamed to {meth}Session.active_pane
    • Session.attached_pane deprecated
  • Window.attached_pane renamed to {meth}Window.active_pane
    • Window.attached_pane deprecated

0.28.0: Resizing and detached by default (2024-02-15)

Detach by default

  • {meth}Session.new_window() + {meth}Window.split_window() no longer attaches by default (#523)

    • 0.28.0 and greater: Defaults to attach=False.
    • 0.27.1 and below: Defaults to attach=True.

    For the old behavior in 0.28.0 and beyond, pass attach=True explicitly.

Resizing panes

  • Pane.resize_pane() renamed to {meth}Pane.resize() (via #523)

    This convention will be more consistent with {meth}Window.resize().

  • {meth}Pane.resize_pane()'s params changed (#523)

    • No longer accepts -U, -D, -L, -R directly, instead accepts {class}~libtmux.constants.ResizeAdjustmentDirection (see below).

      • 0.27.1 and below: pane.resize_pane("-D", 20), pane.resize_pane("-R", 20)

      • 0.28.0 and beyond:

        from libtmux.constants import ResizeAdjustmentDirection
        pane.resize_pane(adjustment_direction=ResizeAdjustmentDirection.Down, adjustment=25)
        pane.resize_pane(
          adjustment_direction=ResizeAdjustmentDirection.Right, adjustment=25
        )

0.17.0: Simplified attributes (2022-12-26)

Finding objects / relations

  • 0.16 and below: session._windows(), session.list_windows(), etc.

    0.17 and after: {attr}session.windows <libtmux.Session.windows>

  • 0.16 and below: session.find_where({'window_name': my_window})

    0.17 and after: {meth}session.windows.get(window_name=my_window, default=None) <libtmux.Session.windows>

    • If not found and not default, raises {exc}~libtmux._internal.query_list.ObjectDoesNotExist
    • If multiple objects found, raises {exc}~libtmux._internal.query_list.MultipleObjectsReturned
  • 0.16 and below: session.where({'window_name': my_window})

    0.17 and after: {meth}session.windows.filter(window_name=my_window) <libtmux.Session.windows>

Accessing attributes

  • 0.16 and below: window['id']

    0.17 and after: window.id

  • 0.16 and below: window.get('id')

    0.17 and after: window.id

  • 0.16 and below: window.get('id', None)

    0.17 and after: getattr(window, 'id', None)