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
1 change: 0 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ repos:
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: python-check-mock-methods
- id: python-no-log-warn
- id: python-use-type-annotations
- id: rst-directive-colons
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased

### Added
- Added env var `TTY_COMPATIBLE` to override auto-detection of TTY support (See console.rst for details). https://github.com/Textualize/rich/pull/3675

### Changed

- An empty `NO_COLOR` env var is now considered disabled. https://github.com/Textualize/rich/pull/3675
- An empty `FORCE_COLOR` env var is now considered disabled. https://github.com/Textualize/rich/pull/3675
- Rich tracebacks will now render notes on Python 3.11 onwards (added with `Exception.add_note`) https://github.com/Textualize/rich/pull/3676


## [13.9.4] - 2024-11-01

### Changed
Expand Down
13 changes: 10 additions & 3 deletions docs/source/console.rst
Original file line number Diff line number Diff line change
Expand Up @@ -420,11 +420,18 @@ Rich respects some standard environment variables.

Setting the environment variable ``TERM`` to ``"dumb"`` or ``"unknown"`` will disable color/style and some features that require moving the cursor, such as progress bars.

If the environment variable ``FORCE_COLOR`` is set, then color/styles will be enabled regardless of the value of ``TERM``. This is useful on CI systems which aren't terminals but can none-the-less display ANSI escape sequences.
If the environment variable ``FORCE_COLOR`` is set and non-empty, then color/styles will be enabled regardless of the value of ``TERM``.

If the environment variable ``NO_COLOR`` is set, Rich will disable all color in the output. This takes precedence over ``FORCE_COLOR``. See `no_color <https://no-color.org/>`_ for details.
If the environment variable ``NO_COLOR`` is set, Rich will disable all color in the output. ``NO_COLOR`` takes precedence over ``FORCE_COLOR``. See `no_color <https://no-color.org/>`_ for details.

.. note::
The ``NO_COLOR`` environment variable removes *color* only. Styles such as dim, bold, italic, underline etc. are preserved.

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.
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 not writing to a terminal. 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.

.. note::
If you want Rich output in CI or Github Actions, then you should set ``TTY_COMPATIBLE=1``.

Note that these variable set the default behavior. If you explicitly set ``force_terminal`` in the Console constructor, then this will take precedence over the environment variables.

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.
28 changes: 21 additions & 7 deletions rich/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ def group(fit: bool = True) -> Callable[..., Callable[..., Group]]:
"""

def decorator(
method: Callable[..., Iterable[RenderableType]]
method: Callable[..., Iterable[RenderableType]],
) -> Callable[..., Group]:
"""Convert a method that returns an iterable of renderables in to a Group."""

Expand Down Expand Up @@ -735,7 +735,9 @@ def __init__(
self.get_time = get_time or monotonic
self.style = style
self.no_color = (
no_color if no_color is not None else "NO_COLOR" in self._environ
no_color
if no_color is not None
else self._environ.get("NO_COLOR", "") != ""
)
self.is_interactive = (
(self.is_terminal and not self.is_dumb_terminal)
Expand Down Expand Up @@ -933,11 +935,13 @@ def is_terminal(self) -> bool:

Returns:
bool: True if the console writing to a device capable of
understanding terminal codes, otherwise False.
understanding escape sequences, otherwise False.
"""
# If dev has explicitly set this value, return it
if self._force_terminal is not None:
return self._force_terminal

# Fudge for Idle
if hasattr(sys.stdin, "__module__") and sys.stdin.__module__.startswith(
"idlelib"
):
Expand All @@ -948,12 +952,22 @@ def is_terminal(self) -> bool:
# return False for Jupyter, which may have FORCE_COLOR set
return False

# If FORCE_COLOR env var has any value at all, we assume a terminal.
force_color = self._environ.get("FORCE_COLOR")
if force_color is not None:
self._force_terminal = True
environ = self._environ

tty_compatible = environ.get("TTY_COMPATIBLE", "")
# 0 indicates device is not tty compatible
if tty_compatible == "0":
return False
# 1 indicates device is tty compatible
if tty_compatible == "1":
return True

# https://force-color.org/
force_color = environ.get("FORCE_COLOR")
if force_color is not None:
return force_color != ""

# Any other value defaults to auto detect
isatty: Optional[Callable[[], bool]] = getattr(self.file, "isatty", None)
try:
return False if isatty is None else isatty()
Expand Down
13 changes: 7 additions & 6 deletions rich/diagnose.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@ def report() -> None: # pragma: no cover
inspect(features)

env_names = (
"TERM",
"COLORTERM",
"CLICOLOR",
"NO_COLOR",
"TERM_PROGRAM",
"COLORTERM",
"COLUMNS",
"LINES",
"JPY_PARENT_PID",
"JUPYTER_COLUMNS",
"JUPYTER_LINES",
"JPY_PARENT_PID",
"LINES",
"NO_COLOR",
"TERM_PROGRAM",
"TERM",
"TTY_COMPATIBLE",
"VSCODE_VERBOSE_LOGGING",
)
env = {name: os.getenv(name) for name in env_names}
Expand Down
Loading
Loading