Skip to content

Commit 863d3da

Browse files
authored
Merge pull request #3675 from Textualize/tty-compatible
TTY_COMPATIBLE
2 parents edc6b0a + 225cb07 commit 863d3da

File tree

6 files changed

+195
-102
lines changed

6 files changed

+195
-102
lines changed

.pre-commit-config.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ repos:
2020
- repo: https://github.com/pre-commit/pygrep-hooks
2121
rev: v1.10.0
2222
hooks:
23-
- id: python-check-mock-methods
2423
- id: python-no-log-warn
2524
- id: python-use-type-annotations
2625
- id: rst-directive-colons

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## Unreleased
99

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

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

19+
1420
## [13.9.4] - 2024-11-01
1521

1622
### Changed

docs/source/console.rst

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,11 +420,18 @@ Rich respects some standard environment variables.
420420

421421
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.
422422

423-
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.
423+
If the environment variable ``FORCE_COLOR`` is set and non-empty, then color/styles will be enabled regardless of the value of ``TERM``.
424424

425-
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.
425+
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.
426426

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

430-
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.
430+
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.
431+
432+
.. note::
433+
If you want Rich output in CI or Github Actions, then you should set ``TTY_COMPATIBLE=1``.
434+
435+
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.
436+
437+
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.

rich/console.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ def group(fit: bool = True) -> Callable[..., Callable[..., Group]]:
500500
"""
501501

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

@@ -735,7 +735,9 @@ def __init__(
735735
self.get_time = get_time or monotonic
736736
self.style = style
737737
self.no_color = (
738-
no_color if no_color is not None else "NO_COLOR" in self._environ
738+
no_color
739+
if no_color is not None
740+
else self._environ.get("NO_COLOR", "") != ""
739741
)
740742
self.is_interactive = (
741743
(self.is_terminal and not self.is_dumb_terminal)
@@ -933,11 +935,13 @@ def is_terminal(self) -> bool:
933935
934936
Returns:
935937
bool: True if the console writing to a device capable of
936-
understanding terminal codes, otherwise False.
938+
understanding escape sequences, otherwise False.
937939
"""
940+
# If dev has explicitly set this value, return it
938941
if self._force_terminal is not None:
939942
return self._force_terminal
940943

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

951-
# If FORCE_COLOR env var has any value at all, we assume a terminal.
952-
force_color = self._environ.get("FORCE_COLOR")
953-
if force_color is not None:
954-
self._force_terminal = True
955+
environ = self._environ
956+
957+
tty_compatible = environ.get("TTY_COMPATIBLE", "")
958+
# 0 indicates device is not tty compatible
959+
if tty_compatible == "0":
960+
return False
961+
# 1 indicates device is tty compatible
962+
if tty_compatible == "1":
955963
return True
956964

965+
# https://force-color.org/
966+
force_color = environ.get("FORCE_COLOR")
967+
if force_color is not None:
968+
return force_color != ""
969+
970+
# Any other value defaults to auto detect
957971
isatty: Optional[Callable[[], bool]] = getattr(self.file, "isatty", None)
958972
try:
959973
return False if isatty is None else isatty()

rich/diagnose.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@ def report() -> None: # pragma: no cover
1515
inspect(features)
1616

1717
env_names = (
18-
"TERM",
19-
"COLORTERM",
2018
"CLICOLOR",
21-
"NO_COLOR",
22-
"TERM_PROGRAM",
19+
"COLORTERM",
2320
"COLUMNS",
24-
"LINES",
21+
"JPY_PARENT_PID",
2522
"JUPYTER_COLUMNS",
2623
"JUPYTER_LINES",
27-
"JPY_PARENT_PID",
24+
"LINES",
25+
"NO_COLOR",
26+
"TERM_PROGRAM",
27+
"TERM",
28+
"TTY_COMPATIBLE",
2829
"VSCODE_VERBOSE_LOGGING",
2930
)
3031
env = {name: os.getenv(name) for name in env_names}

0 commit comments

Comments
 (0)