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

use larger width/height defaults for non-interactive consoles #3270

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ttarabula
Copy link

@ttarabula ttarabula commented Feb 2, 2024

When a user is redirecting output to a file, or perhaps running a job non-interactively (say, via cron), arguably, it is surprising when output (such as a rich.table) is truncated to a default size of (80, 25). This change preserves that default Console.size() -> width=80, height=25, but uses larger defaults when Console.is_interactive == False.

Type of changes

  • Bug fix
  • New feature
  • Documentation / docstrings
  • Tests
  • Other

Checklist

  • I've run the latest black with default args on new code.
  • I've updated CHANGELOG.md and CONTRIBUTORS.md where appropriate.
  • I've added tests for new code.
  • I accept that @willmcgugan may be pedantic in the code review.

Description

I am not at all sure that I'm solving the right problem here or going about it correctly, but I prefer describing what I'm trying to accomplish, via code (pull request) rather than simply descriptively, via a project issue. The basic idea here is that I personally find the following result surprising:

given the following table test (basically pulled directly from the example in the documentation, here: https://rich.readthedocs.io/en/stable/tables.html#tables):

#!/usr/bin/env python
from rich.console import Console
from rich.table import Table

table = Table(title="Star Wars Movies")

table.add_column("Released", justify="right", style="cyan", no_wrap=True)
table.add_column("Title", style="magenta")
table.add_column("Box Office", justify="right", style="green")

table.add_row("Dec 20, 2019", "Star Wars: The Rise of Skywalker", "$952,110,690")
table.add_row("May 25, 2018", "Solo: A Star Wars Story", "$393,151,347")
table.add_row("Dec 15, 2017", "Star Wars Ep. V111: The Last Jedi", "$1,332,539,889")
table.add_row("Dec 16, 2016", "Rogue One: A Star Wars Story", "$1,332,439,889")
table.add_row("May 22, 2026", "As Yet Unnamed Amazing Next Star Wars Movie With A Really Long Name", "$999,999,999,999")

console = Console()
console.print(table)

I like that it truncates the table to my terminal width/height when running it interactively (say, ./print_rich_table.py), but would prefer that it doesn't truncate and/or wrap when non-interactive, for instance, when redirecting to a file (./print_rich_table.py > star_wars.txt), or perhaps running a job via cron or in some other way where the expectation is for the handling of display constraints to be handled by some later user who may not be the original script runner.

I've tested this change by shrinking/growing my terminal and making sure the old behavior is preserved, as well as by updating tests/test_console.py with some new cases.

I'm happy to try to take another approach here if this doesn't make sense. Also, of course, I picked the new defaults out of thin air (just trying to come up with some reasonably large numbers to prove out the strategy).

When a user is redirecting output to a file, or perhaps running a job
non-interactively (say, via cron), arguably, it is surprising when
output (such as a rich.table) is truncated to a default size of (80,
25). This change preserves that default Console.size() -> width=80, height=25, but uses larger defaults when Console.is_interactive == False.
Copy link
Collaborator

@willmcgugan willmcgugan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bad idea. You wouldn't want a rule or table to be 32767 characters long.

@ttarabula
Copy link
Author

ttarabula commented Feb 29, 2024

This is a bad idea. You wouldn't want a rule or table to be 32767 characters long.

Ah, I fully concede that this might be bad to handle it this way, but let me try to explain my actual end goal here a little bit more clearly, in case there's another way towards what I'm trying to achieve...

In our environment, we use rich.table (which we love!) in various ways. It is incredibly helpful for rich to fit output tables to the width of a terminal when a user is doing ad-hoc interactive work. However, we have many use cases where the output of a job that has rich.table components, goes to a text file for later analysis/viewing or perhaps gets piped to something else (like grep for instance). We typically don't want any sort of truncation of that data in those scenarios. That is, the user would happily resize their terminal and/or scroll horizontally to look through the table. They generally want to see all of the field values, without any truncation. Consider especially the use case where we can't predict in advance what the min/max column/width boundaries are expected to be, and perhaps even won't be looking at the output until weeks after it was saved. Of course, one could argue that rich.table isn't the right tool for this job, and outputting as some sort of standard table format instead (such as csv) makes more sense, but there are many use cases where it's just simpler or more user friendly for there to be a expectation of visual consistency (ie, the user looks through these sorts of tables all the time, and is more efficiently able to glance at it when it has the same look and feel as what they see interactively).

My assertion is really that I don't believe that console dimensions or a default (such as 80x25) should be used at all in those cases (ie, my large number was "pseudo-infinite" for practical purposes).

We can certainly work around this, but it is relatively burdensome to the developer to manage this on a per-script basis, rather than it being a core behavior of rich, or at least modifiable at a high level (perhaps a flag that gets passed to the rich.console.Console() constructor, optionally, that maybe defaults to the current behavior, and changes to the behavior if specified).

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

Successfully merging this pull request may close these issues.

None yet

2 participants