Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 23 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,29 @@ _Upcoming changes will be written here._
- Fix incorrect return type annotations for `capture_pane()` and `display_message()` methods
(changed from `str | list[str]` to `list[str]` - the methods always return a list).

#### APIs deprecated (#611)

Legacy API methods (deprecated in 0.16-0.33) now raise {exc}`~libtmux.exc.DeprecatedError` (hard error) instead of emitting {class}`DeprecationWarning`.

See {doc}`migration` for full context and examples.

| Deprecated API | Replacement | Deprecated | Raises | Note |
|----------------|-------------|------------|--------|------|
| `kill_server()` | {meth}`~libtmux.Server.kill` | 0.30.0 | 0.51.0 | Server |
| `attach_session()`, `kill_session()` | {meth}`~libtmux.Session.attach`, {meth}`~libtmux.Session.kill` | 0.30.0 | 0.51.0 | Session |
| `select_window()`, `kill_window()`, `split_window()` | {meth}`~libtmux.Window.select`, {meth}`~libtmux.Window.kill`, {meth}`~libtmux.Window.split` | 0.30.0 / 0.33.0 | 0.51.0 | Window |
| `resize_pane()`, `select_pane()`, `split_window()` | {meth}`~libtmux.Pane.resize`, {meth}`~libtmux.Pane.select`, {meth}`~libtmux.Pane.split` | 0.28.0 / 0.30.0 / 0.33.0 | 0.51.0 | Pane |
| `attached_window`, `attached_pane` | {attr}`~libtmux.Session.active_window`, {attr}`~libtmux.Session.active_pane` / {attr}`~libtmux.Window.active_pane` | 0.31.0 | 0.51.0 | Session/Window |
| `list_*()`, `_list_*()`, `_update_*()`, `children`, `where()`, `find_where()`, `get_by_id()` | {attr}`~libtmux.Server.sessions` / {attr}`~libtmux.Session.windows` / {attr}`~libtmux.Window.panes` with {meth}`~libtmux.common.QueryList.filter` / {meth}`~libtmux.common.QueryList.get` | 0.16.0 / 0.17.0 | 0.51.0 | Query/filter helpers |
| Dict-style access (`obj["key"]`, `obj.get(...)`) | Attribute access (e.g., {attr}`~libtmux.window.Window.window_name`) | 0.17.0 | 0.51.0 | All tmux objects |

The following deprecations from 0.50.0 continue to emit {class}`DeprecationWarning` (soft deprecation):

| Deprecated API | Replacement | Deprecated | Note |
|----------------|-------------|------------|------|
| `set_window_option()`, `show_window_option()`, `show_window_options()` | {meth}`~libtmux.window.Window.set_option`, {meth}`~libtmux.window.Window.show_option`, {meth}`~libtmux.window.Window.show_options` | 0.50.0 | Window |
| `g` parameter on options/hooks methods | `global_` on {meth}`~libtmux.options.OptionsMixin.set_option`, {meth}`~libtmux.options.OptionsMixin.show_option`, {meth}`~libtmux.options.OptionsMixin.show_options` | 0.50.0 | Options & hooks |

## libtmux 0.50.0 (2025-11-30)

### Overview
Expand Down
88 changes: 88 additions & 0 deletions MIGRATION
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,94 @@ well.
[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._
Expand Down
29 changes: 29 additions & 0 deletions src/libtmux/exc.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,35 @@ class LibTmuxException(Exception):
"""Base Exception for libtmux Errors."""


class DeprecatedError(LibTmuxException):
"""Raised when a deprecated function, method, or parameter is used.

This exception provides clear guidance on what to use instead.

Parameters
----------
deprecated : str
The name of the deprecated API (e.g., "Pane.resize_pane()")
replacement : str
The recommended replacement API to use instead
version : str
The version when the API was deprecated (e.g., "0.28.0")
"""

def __init__(
self,
*,
deprecated: str,
replacement: str,
version: str,
) -> None:
msg = (
f"{deprecated} was deprecated in {version} and has been removed. "
f"Use {replacement} instead."
)
super().__init__(msg)


class TmuxSessionExists(LibTmuxException):
"""Session does not exist in the server."""

Expand Down
34 changes: 21 additions & 13 deletions src/libtmux/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -797,8 +797,9 @@ def _show_options_raw(

Parameters
----------
g : str, optional
Pass ``-g`` flag for global variable, default False.
g : bool, optional
.. deprecated:: 0.50.0
Use ``global_`` instead.

Examples
--------
Expand Down Expand Up @@ -834,8 +835,9 @@ def _show_options_raw(
category=DeprecationWarning,
stacklevel=2,
)
flags += ("-g",)
elif global_:
global_ = g

if global_:
flags += ("-g",)

if scope is not None and not isinstance(scope, _DefaultOptionScope):
Expand Down Expand Up @@ -864,8 +866,9 @@ def _show_options_dict(

Parameters
----------
g : str, optional
Pass ``-g`` flag for global variable, default False.
g : bool, optional
.. deprecated:: 0.50.0
Use ``global_`` instead.

Examples
--------
Expand Down Expand Up @@ -913,8 +916,9 @@ def _show_options(

Parameters
----------
g : str, optional
Pass ``-g`` flag for global variable, default False.
g : bool, optional
.. deprecated:: 0.50.0
Use ``global_`` instead.

Examples
--------
Expand Down Expand Up @@ -1013,7 +1017,8 @@ def _show_option_raw(
----------
option : str
g : bool, optional
Pass ``-g`` flag, global. Default False.
.. deprecated:: 0.50.0
Use ``global_`` instead.

Raises
------
Expand Down Expand Up @@ -1063,8 +1068,9 @@ def _show_option_raw(
category=DeprecationWarning,
stacklevel=2,
)
flags += ("-g",)
elif global_:
global_ = g

if global_:
flags += ("-g",)

if scope is not None and not isinstance(scope, _DefaultOptionScope):
Expand Down Expand Up @@ -1104,7 +1110,8 @@ def _show_option(
----------
option : str
g : bool, optional
Pass ``-g`` flag, global. Default False.
.. deprecated:: 0.50.0
Use ``global_`` instead.

Raises
------
Expand Down Expand Up @@ -1206,7 +1213,8 @@ def show_option(
----------
option : str
g : bool, optional
Pass ``-g`` flag, global. Default False.
.. deprecated:: 0.50.0
Use ``global_`` instead.

Raises
------
Expand Down
76 changes: 24 additions & 52 deletions src/libtmux/pane.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import logging
import pathlib
import typing as t
import warnings

from libtmux import exc
from libtmux.common import tmux_cmd
Expand Down Expand Up @@ -554,16 +553,11 @@ def select_pane(self) -> Pane:

Deprecated in favor of :meth:`.select()`.
"""
warnings.warn(
"Pane.select_pane() is deprecated in favor of Pane.select()",
category=DeprecationWarning,
stacklevel=2,
raise exc.DeprecatedError(
deprecated="Pane.select_pane()",
replacement="Pane.select()",
version="0.30.0",
)
assert isinstance(self.pane_id, str)
pane = self.window.select_pane(self.pane_id)
if pane is None:
raise exc.PaneNotFound(pane_id=self.pane_id)
return pane

def split(
self,
Expand Down Expand Up @@ -731,7 +725,7 @@ def set_width(self, width: int) -> Pane:
:class:`Pane`
Self, for method chaining.
"""
self.resize_pane(width=width)
self.resize(width=width)
return self

def set_height(self, height: int) -> Pane:
Expand All @@ -747,7 +741,7 @@ def set_height(self, height: int) -> Pane:
:class:`Pane`
Self, for method chaining.
"""
self.resize_pane(height=height)
self.resize(height=height)
return self

def enter(self) -> Pane:
Expand Down Expand Up @@ -915,54 +909,41 @@ def split_window(

Deprecated in favor of :meth:`.split`.
"""
warnings.warn(
"Pane.split_window() is deprecated in favor of Pane.split()",
category=DeprecationWarning,
stacklevel=2,
)
if size is None and percent is not None:
size = f"{str(percent).rstrip('%')}%"
return self.split(
target=target,
attach=attach,
start_directory=start_directory,
direction=PaneDirection.Below if vertical else PaneDirection.Right,
shell=shell,
size=size,
environment=environment,
raise exc.DeprecatedError(
deprecated="Pane.split_window()",
replacement="Pane.split()",
version="0.33.0",
)

def get(self, key: str, default: t.Any | None = None) -> t.Any:
"""Return key-based lookup. Deprecated by attributes.

.. deprecated:: 0.16
.. deprecated:: 0.17

Deprecated by attribute lookup, e.g. ``pane['window_name']`` is now
accessed via ``pane.window_name``.

"""
warnings.warn(
"Pane.get() is deprecated",
category=DeprecationWarning,
stacklevel=2,
raise exc.DeprecatedError(
deprecated="Pane.get()",
replacement="direct attribute access (e.g., pane.pane_id)",
version="0.17.0",
)
return getattr(self, key, default)

def __getitem__(self, key: str) -> t.Any:
"""Return item lookup by key. Deprecated in favor of attributes.

.. deprecated:: 0.16
.. deprecated:: 0.17

Deprecated in favor of attributes. e.g. ``pane['window_name']`` is now
accessed via ``pane.window_name``.

"""
warnings.warn(
f"Item lookups, e.g. pane['{key}'] is deprecated",
category=DeprecationWarning,
stacklevel=2,
raise exc.DeprecatedError(
deprecated="Pane[key] lookup",
replacement="direct attribute access (e.g., pane.pane_id)",
version="0.17.0",
)
return getattr(self, key)

def resize_pane(
self,
Expand All @@ -985,17 +966,8 @@ def resize_pane(

Deprecated by :meth:`Pane.resize`.
"""
warnings.warn(
"Deprecated: Use Pane.resize() instead of Pane.resize_pane()",
category=DeprecationWarning,
stacklevel=2,
)
return self.resize(
adjustment_direction=adjustment_direction,
adjustment=adjustment,
height=height,
width=width,
zoom=zoom,
mouse=mouse,
trim_below=trim_below,
raise exc.DeprecatedError(
deprecated="Pane.resize_pane()",
replacement="Pane.resize()",
version="0.28.0",
)
Loading