← oracle_full

rich_3675

resolved RESOLVED UNSUBMITTED PASS · None tool calls · 0 s · Textualize/rich

Task input

TTY_COMPATIBLE

Implement new `TTY_COMPATIBLE` environment variable

@ofek @webknjaz @hugovk 

Relevant discussion: https://github.com/Textualize/rich/issues/2924

Tool calls (0)

#ToolArgumentsResult
No trace captured.

Patch

--- a/rich/console.py
+++ b/rich/console.py
@@ -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."""
 
@@ -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)
@@ -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"
         ):
@@ -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()
--- a/rich/diagnose.py
+++ b/rich/diagnose.py
@@ -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}

Test output

show
........................................................................ [ 72%]
...........................                                              [100%]
99 passed in 0.71s