From 0ab2467297190cdf09dde9256ce26d4e7e18ff3a Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 20 Jun 2025 21:23:40 +0100 Subject: [PATCH 1/4] TTY_INTERACTIVE env var --- CHANGELOG.md | 4 ++++ docs/source/console.rst | 6 +++--- rich/console.py | 12 +++++++++++- rich/diagnose.py | 1 + tests/test_console.py | 25 +++++++++++++++++++++++++ 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 490857b35c..407c85a472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed extraction of recursive exceptions https://github.com/Textualize/rich/pull/3772 +### Addedd + +- Added `TTY_INTERACTIVE` environment variable to force interactive mode off or on. + ## [14.0.0] - 2025-03-30 ### Added diff --git a/docs/source/console.rst b/docs/source/console.rst index c0d50ca18d..b18a7710b8 100644 --- a/docs/source/console.rst +++ b/docs/source/console.rst @@ -410,8 +410,6 @@ Interactive mode Rich will remove animations such as progress bars and status indicators when not writing to a terminal as you probably don't want to write these out to a text file (for example). You can override this behavior by setting the ``force_interactive`` argument on the constructor. Set it to True to enable animations or False to disable them. -.. note:: - Some CI systems support ANSI color and style but not anything that moves the cursor or selectively refreshes parts of the terminal. For these you might want to set ``force_terminal`` to ``True`` and ``force_interactive`` to ``False``. Environment variables --------------------- @@ -429,8 +427,10 @@ If the environment variable ``NO_COLOR`` is set, Rich will disable all color in The environment variable ``TTY_COMPATIBLE`` is used to override Rich's auto-detection of terminal support. If ``TTY_COMPATIBLE`` is set to ``1`` then Rich will assume it is writing to a device which can handle escape sequences like a terminal. If ``TTY_COMPATIBLE`` is set to ``"0"``, then Rich will assume that it is writing to a device that is *not* capable of displaying escape sequences (such as a regular file). If the variable is not set, or set to a value other than "0" or "1", then Rich will attempt to auto-detect terminal support. +The environment variable ``TTY_INTERACTIVE`` is used to override Rich's auto-detection of interactive mode (see above). If you set this to ``"0"``, it will disable interactive mode even if Rich thinks it is writing to a terminal. Set this to ``"1"`` to force interactive mode on. If this environment variable is not set, or set to any other value, then interactive mode will be auto-detected as normal. + .. note:: - If you want Rich output in CI or Github Actions, then you should set ``TTY_COMPATIBLE=1``. + If you want Rich output in CI or Github Actions, then you should set ``TTY_COMPATIBLE=1`` and ``TTY_INTERACTIVE=0``. If ``width`` / ``height`` arguments are not explicitly provided as arguments to ``Console`` then the environment variables ``COLUMNS`` / ``LINES`` can be used to set the console width / height. ``JUPYTER_COLUMNS`` / ``JUPYTER_LINES`` behave similarly and are used in Jupyter. diff --git a/rich/console.py b/rich/console.py index 5929fb1c56..7d4d4a8f64 100644 --- a/rich/console.py +++ b/rich/console.py @@ -22,18 +22,20 @@ Dict, Iterable, List, + Literal, Mapping, NamedTuple, Optional, + Protocol, TextIO, Tuple, Type, Union, cast, + runtime_checkable, ) from rich._null_file import NULL_FILE -from typing import Literal, Protocol, runtime_checkable from . import errors, themes from ._emoji_replace import _emoji_replace @@ -731,6 +733,14 @@ def __init__( if no_color is not None else self._environ.get("NO_COLOR", "") != "" ) + if force_interactive is None: + tty_interactive = self._environ.get("TTY_INTERACTIVE", None) + if tty_interactive is not None: + if tty_interactive == "0": + force_interactive = False + elif tty_interactive == "1": + force_interactive = True + self.is_interactive = ( (self.is_terminal and not self.is_dumb_terminal) if force_interactive is None diff --git a/rich/diagnose.py b/rich/diagnose.py index 5d163877da..9d5ff3ec32 100644 --- a/rich/diagnose.py +++ b/rich/diagnose.py @@ -26,6 +26,7 @@ def report() -> None: # pragma: no cover "TERM_PROGRAM", "TERM", "TTY_COMPATIBLE", + "TTY_INTERACTIVE", "VSCODE_VERBOSE_LOGGING", ) env = {name: os.getenv(name) for name in env_names} diff --git a/tests/test_console.py b/tests/test_console.py index 10576b2dae..499043b312 100644 --- a/tests/test_console.py +++ b/tests/test_console.py @@ -1038,6 +1038,31 @@ def test_capture_and_record() -> None: assert recorded_content == "Print 0\n" +def test_tty_interactive() -> None: + """Check TTY_INTERACTIVE environment var.""" + + # Bytes file, not interactive + console = Console(file=io.BytesIO()) + assert not console.is_interactive + + # Bytes file, force interactive + console = Console(file=io.BytesIO(), _environ={"TTY_INTERACTIVE": "1"}) + assert console.is_interactive + + # Force tty compatible, should be interactive + console = Console(file=io.BytesIO(), _environ={"TTY_COMPATIBLE": "1"}) + assert console.is_interactive + + # Force tty compatible, force not interactive + console = Console( + file=io.BytesIO(), _environ={"TTY_COMPATIBLE": "1", "TTY_INTERACTIVE": "0"} + ) + + # Bytes file, Unknown value of TTY_INTERACTIVE should still auto-detect + console = Console(file=io.BytesIO(), _environ={"TTY_INTERACTIVE": "foo"}) + assert not console.is_interactive + + def test_tty_compatible() -> None: """Check TTY_COMPATIBLE environment var.""" From 8cd74506b1d826ddc29d02f7eede6fb9b70fc2f0 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Fri, 20 Jun 2025 21:24:32 +0100 Subject: [PATCH 2/4] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 407c85a472..a3e2c0acbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Addedd -- Added `TTY_INTERACTIVE` environment variable to force interactive mode off or on. +- Added `TTY_INTERACTIVE` environment variable to force interactive mode off or on https://github.com/Textualize/rich/pull/3777 ## [14.0.0] - 2025-03-30 From 589dc00b6ed17c28ac8c33d48d4bd460d7ea6cd2 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 23 Jun 2025 16:56:33 +0100 Subject: [PATCH 3/4] text --- docs/source/console.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/source/console.rst b/docs/source/console.rst index b18a7710b8..4d79886c24 100644 --- a/docs/source/console.rst +++ b/docs/source/console.rst @@ -405,10 +405,12 @@ If Rich detects that it is not writing to a terminal it will strip control codes Letting Rich auto-detect terminals is useful as it will write plain text when you pipe output to a file or other application. +.. _interactive_mode: + Interactive mode ---------------- -Rich will remove animations such as progress bars and status indicators when not writing to a terminal as you probably don't want to write these out to a text file (for example). You can override this behavior by setting the ``force_interactive`` argument on the constructor. Set it to True to enable animations or False to disable them. +Rich will remove animations such as progress bars and status indicators when not writing to a terminal as you probably don't want to write these out to a text file (for example). You can override this behavior by setting the ``force_interactive`` argument on the constructor. Set it to ``True`` to enable animations or ``False`` to disable them. Environment variables @@ -427,10 +429,11 @@ If the environment variable ``NO_COLOR`` is set, Rich will disable all color in The environment variable ``TTY_COMPATIBLE`` is used to override Rich's auto-detection of terminal support. If ``TTY_COMPATIBLE`` is set to ``1`` then Rich will assume it is writing to a device which can handle escape sequences like a terminal. If ``TTY_COMPATIBLE`` is set to ``"0"``, then Rich will assume that it is writing to a device that is *not* capable of displaying escape sequences (such as a regular file). If the variable is not set, or set to a value other than "0" or "1", then Rich will attempt to auto-detect terminal support. -The environment variable ``TTY_INTERACTIVE`` is used to override Rich's auto-detection of interactive mode (see above). If you set this to ``"0"``, it will disable interactive mode even if Rich thinks it is writing to a terminal. Set this to ``"1"`` to force interactive mode on. If this environment variable is not set, or set to any other value, then interactive mode will be auto-detected as normal. +The environment variable ``TTY_INTERACTIVE`` is used to override Rich's auto-detection of :ref:`interactive_mode`. If you set this to ``"0"``, it will disable interactive mode even if Rich thinks it is writing to a terminal. Set this to ``"1"`` to force interactive mode on. If this environment variable is not set, or set to any other value, then interactive mode will be auto-detected as normal. .. note:: - If you want Rich output in CI or Github Actions, then you should set ``TTY_COMPATIBLE=1`` and ``TTY_INTERACTIVE=0``. + If you want Rich output in CI or Github Actions, then you should set ``TTY_COMPATIBLE=1`` and ``TTY_INTERACTIVE=0``. The combination of both these variables tells rich that it can output escape sequences, + and also that there is no user interacting with the terminal -- so it won't bother animating progress bars. If ``width`` / ``height`` arguments are not explicitly provided as arguments to ``Console`` then the environment variables ``COLUMNS`` / ``LINES`` can be used to set the console width / height. ``JUPYTER_COLUMNS`` / ``JUPYTER_LINES`` behave similarly and are used in Jupyter. From b46bd78ee5c665172d936adca111a9b54420f675 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 23 Jun 2025 16:58:48 +0100 Subject: [PATCH 4/4] typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3e2c0acbf..c5b1877289 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed extraction of recursive exceptions https://github.com/Textualize/rich/pull/3772 -### Addedd +### Added - Added `TTY_INTERACTIVE` environment variable to force interactive mode off or on https://github.com/Textualize/rich/pull/3777