Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Captured console output still results in newline being printed in Jupyter #3274

Open
2 tasks done
huzecong opened this issue Feb 6, 2024 · 1 comment · May be fixed by #3329
Open
2 tasks done

[BUG] Captured console output still results in newline being printed in Jupyter #3274

huzecong opened this issue Feb 6, 2024 · 1 comment · May be fixed by #3329

Comments

@huzecong
Copy link

huzecong commented Feb 6, 2024

Describe the bug

When using console.capture() in Jupyter, a new line gets printed to the notebook when exiting the capture context. This is unexpected, and is also different from rich's behavior in terminal (no new lines printed).

Here's a minimal example. After running the following in a Jupyter cell, 100 new lines are printed:

import rich.console

console = rich.console.Console()
for _ in range(100):
    with console.capture() as capture:
        console.print(1)

I think the issue is within Console._check_buffer. When exiting a capture context, self._render_buffer(self._buffer[:]) returns an empty string. When not in Jupyter, we eventually call self.file.write which is no-op when the text is empty. However, in Jupyter we'd call IPython.display.display, which IIUC always results in an empty line.

rich/rich/console.py

Lines 2003 to 2066 in 26152e9

if self._buffer_index == 0:
if self.is_jupyter: # pragma: no cover
from .jupyter import display
display(self._buffer, self._render_buffer(self._buffer[:]))
del self._buffer[:]
else:
if WINDOWS:
use_legacy_windows_render = False
if self.legacy_windows:
fileno = get_fileno(self.file)
if fileno is not None:
use_legacy_windows_render = (
fileno in _STD_STREAMS_OUTPUT
)
if use_legacy_windows_render:
from rich._win32_console import LegacyWindowsTerm
from rich._windows_renderer import legacy_windows_render
buffer = self._buffer[:]
if self.no_color and self._color_system:
buffer = list(Segment.remove_color(buffer))
legacy_windows_render(buffer, LegacyWindowsTerm(self.file))
else:
# Either a non-std stream on legacy Windows, or modern Windows.
text = self._render_buffer(self._buffer[:])
# https://bugs.python.org/issue37871
# https://github.com/python/cpython/issues/82052
# We need to avoid writing more than 32Kb in a single write, due to the above bug
write = self.file.write
# Worse case scenario, every character is 4 bytes of utf-8
MAX_WRITE = 32 * 1024 // 4
try:
if len(text) <= MAX_WRITE:
write(text)
else:
batch: List[str] = []
batch_append = batch.append
size = 0
for line in text.splitlines(True):
if size + len(line) > MAX_WRITE and batch:
write("".join(batch))
batch.clear()
size = 0
batch_append(line)
size += len(line)
if batch:
write("".join(batch))
batch.clear()
except UnicodeEncodeError as error:
error.reason = f"{error.reason}\n*** You may need to add PYTHONIOENCODING=utf-8 to your environment ***"
raise
else:
text = self._render_buffer(self._buffer[:])
try:
self.file.write(text)
except UnicodeEncodeError as error:
error.reason = f"{error.reason}\n*** You may need to add PYTHONIOENCODING=utf-8 to your environment ***"
raise
self.file.flush()
del self._buffer[:]

Platform

Click to expand

What platform (Win/Linux/Mac) are you running on? What terminal software are you using?

I may ask you to copy and paste the output of the following commands. It may save some time if you do it now.

If you're using Rich in a terminal:

python -m rich.diagnose
pip freeze | grep rich

If you're using Rich in a Jupyter Notebook, run the following snippet in a cell
and paste the output in your bug report.

from rich.diagnose import report
report()

╭────────────────────── <class 'rich.console.Console'> ──────────────────────╮
│ A high level console interface.                                            │
│                                                                            │
│ ╭────────────────────────────────────────────────────────────────────────╮ │
│ │ <console width=115 ColorSystem.TRUECOLOR>                              │ │
│ ╰────────────────────────────────────────────────────────────────────────╯ │
│                                                                            │
│     color_system = 'truecolor'                                             │
│         encoding = 'utf-8'                                                 │
│             file = <ipykernel.iostream.OutStream object at 0x7f8bf0a35090> │
│           height = 100                                                     │
│    is_alt_screen = False                                                   │
│ is_dumb_terminal = False                                                   │
│   is_interactive = False                                                   │
│       is_jupyter = True                                                    │
│      is_terminal = False                                                   │
│   legacy_windows = False                                                   │
│         no_color = False                                                   │
│          options = ConsoleOptions(                                         │
│                        size=ConsoleDimensions(width=115, height=100),      │
│                        legacy_windows=False,                               │
│                        min_width=1,                                        │
│                        max_width=115,                                      │
│                        is_terminal=False,                                  │
│                        encoding='utf-8',                                   │
│                        max_height=100,                                     │
│                        justify=None,                                       │
│                        overflow=None,                                      │
│                        no_wrap=False,                                      │
│                        highlight=None,                                     │
│                        markup=None,                                        │
│                        height=None                                         │
│                    )                                                       │
│            quiet = False                                                   │
│           record = False                                                   │
│         safe_box = True                                                    │
│             size = ConsoleDimensions(width=115, height=100)                │
│        soft_wrap = False                                                   │
│           stderr = False                                                   │
│            style = None                                                    │
│         tab_size = 8                                                       │
│            width = 115                                                     │
╰────────────────────────────────────────────────────────────────────────────╯
╭─── <class 'rich._windows.WindowsConsoleFeatures'> ────╮
│ Windows features available.                           │
│                                                       │
│ ╭───────────────────────────────────────────────────╮ │
│ │ WindowsConsoleFeatures(vt=False, truecolor=False) │ │
│ ╰───────────────────────────────────────────────────╯ │
│                                                       │
│ truecolor = False                                     │
│        vt = False                                     │
╰───────────────────────────────────────────────────────╯
╭────── Environment Variables ───────╮
│ {                                  │
│     'TERM': 'xterm-color',         │
│     'COLORTERM': None,             │
│     'CLICOLOR': '1',               │
│     'NO_COLOR': None,              │
│     'TERM_PROGRAM': 'tmux',        │
│     'COLUMNS': None,               │
│     'LINES': None,                 │
│     'JUPYTER_COLUMNS': None,       │
│     'JUPYTER_LINES': None,         │
│     'JPY_PARENT_PID': '112278',    │
│     'VSCODE_VERBOSE_LOGGING': None │
│ }                                  │
╰────────────────────────────────────╯
platform="Linux"
Copy link

github-actions bot commented Feb 6, 2024

We found the following entries in the FAQ which you may find helpful:

Feel free to close this issue if you found an answer in the FAQ. Otherwise, please give us a little time to review.

This is an automated reply, generated by FAQtory

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant