Textualize / rich

Rich is a Python library for rich text and beautiful formatting in the terminal.
https://rich.readthedocs.io/en/latest/
MIT License
48.87k stars 1.71k forks source link

[BUG] console.status flutter #3451

Open pdimens opened 1 month ago

pdimens commented 1 month ago

Describe the bug When using console.status() with a while True block inside it, the console text has a persistent flutter. Notably:

Kooha-2024-08-13-10-32-13.webm

Minimal example

For context, this process is intercepting the output text of Snakemake (invoked with subprocess.Popen())

console = Console()
with console.status("[magenta]Downloading and installing workflow dependencies", spinner = "point") as status:
  while True:
    output = process.stderr.readline()
    if output == '' and process.poll() is not None:
      break
    sleep(2)
    if output.startswith("Job stats:"):
      break

Platform Information

Click to expand What platform (Win/Linux/Mac) are you running on? What terminal software are you using? Linux. Terminal via VScode and Konsole ``` ╭───────────────────── ─────────────────────╮ │ A high level console interface. │ │ │ │ ╭──────────────────────────────────────────────────────────────────────╮ │ │ │ │ │ │ ╰──────────────────────────────────────────────────────────────────────╯ │ │ │ │ color_system = 'truecolor' │ │ encoding = 'utf-8' │ │ file = <_io.TextIOWrapper name='' mode='w' │ │ encoding='utf-8'> │ │ height = 53 │ │ is_alt_screen = False │ │ is_dumb_terminal = False │ │ is_interactive = True │ │ is_jupyter = False │ │ is_terminal = True │ │ legacy_windows = False │ │ no_color = False │ │ options = ConsoleOptions( │ │ size=ConsoleDimensions(width=76, height=53), │ │ legacy_windows=False, │ │ min_width=1, │ │ max_width=76, │ │ is_terminal=True, │ │ encoding='utf-8', │ │ max_height=53, │ │ justify=None, │ │ overflow=None, │ │ no_wrap=False, │ │ highlight=None, │ │ markup=None, │ │ height=None │ │ ) │ │ quiet = False │ │ record = False │ │ safe_box = True │ │ size = ConsoleDimensions(width=76, height=53) │ │ soft_wrap = False │ │ stderr = False │ │ style = None │ │ tab_size = 8 │ │ width = 76 │ ╰──────────────────────────────────────────────────────────────────────────╯ ╭─── ────╮ │ Windows features available. │ │ │ │ ╭───────────────────────────────────────────────────╮ │ │ │ WindowsConsoleFeatures(vt=False, truecolor=False) │ │ │ ╰───────────────────────────────────────────────────╯ │ │ │ │ truecolor = False │ │ vt = False │ ╰───────────────────────────────────────────────────────╯ ╭────── Environment Variables ───────╮ │ { │ │ 'TERM': 'xterm-256color', │ │ 'COLORTERM': 'truecolor', │ │ 'CLICOLOR': None, │ │ 'NO_COLOR': None, │ │ 'TERM_PROGRAM': 'vscode', │ │ 'COLUMNS': None, │ │ 'LINES': None, │ │ 'JUPYTER_COLUMNS': None, │ │ 'JUPYTER_LINES': None, │ │ 'JPY_PARENT_PID': None, │ │ 'VSCODE_VERBOSE_LOGGING': None │ │ } │ ╰────────────────────────────────────╯ platform="Linux" rich @ file:///home/conda/feedstock_root/build_artifacts/rich-split_1709150387247/work/dist rich-click @ file:///home/conda/feedstock_root/build_artifacts/rich-click_1704476299123/work ```
github-actions[bot] commented 1 month ago

Thank you for your issue. Give us a little time to review it.

PS. You might want to check the FAQ if you haven't done so already.

This is an automated reply, generated by FAQtory

cilki commented 1 month ago

Same issue here with progress bars + spinner. Seems to get worse as the system load increases.

subrat-lima commented 1 month ago

Hi @pdimens and @cilki, could you please share a full sample code that causes the issue. It would be helpful to replicate and debug the issue.

pdimens commented 1 month ago

I tried to do something similar as a toy example and the flutter only occurs when the console block is nested in a progress block:

#! /usr/bin/env python
from time import sleep
from rich.console import Console
from rich.progress import Progress

i = 0
with Progress() as progress:
    console = Console()
    with console.status("text text text", spinner = "point") as status:
        while True:
            sleep(2)
            i += 1
            if i >10:
                break

same behavior if their blocks appear together:

i = 0
console = Console()
with Progress() as progress, console.status("text text text", spinner = "point") as status:
    while True:
        sleep(2)
        i += 1
        if i >10:
            break
cilki commented 1 month ago

I tried to do something similar as a toy example and the flutter only occurs when the console block is nested in a progress block:

#! /usr/bin/env python
from time import sleep
from rich.console import Console
from rich.progress import Progress

i = 0
with Progress() as progress:
    console = Console()
    with console.status("text text text", spinner = "point") as status:
        while True:
            sleep(2)
            i += 1
            if i >10:
                break

Confirmed this flickers for me too on Python 3.11/3.12 and rich 13.7.1 on Linux.

subrat-lima commented 1 month ago

Thanks a lot @pdimens and @cilki, examples were helpful and I was able to replicate the issue.

Progress and Console status both animate the display and I suspect that they both interfere with each other's update cycle and should not be mixed together. However, I've yet to check the code base to confirm this.

Meanwhile, I was able to get similar functionality with use of either one if it helps.

#! /usr/bin/env python
from time import sleep
from rich.console import Console

i = 1
console = Console()
with console.status("console.status update ...", spinner="point") as status:
    while True:
        sleep(1)
        i += 1
        if i > 5:
            break
#! /usr/bin/env python
from time import sleep
from rich.progress import Progress

i = 1
with Progress() as progress:
    task = progress.add_task("[green]progress update ...", total=None)
    while True:
        sleep(1)
        i += 1
        if i > 5:
            break