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

Wrapping bug in connection with terminal size #40

Open
thorstenkampe opened this issue Jun 11, 2017 · 3 comments
Open

Wrapping bug in connection with terminal size #40

thorstenkampe opened this issue Jun 11, 2017 · 3 comments

Comments

@thorstenkampe
Copy link

Hi,

the following code triggers a wrapping bug in connection with the terminal size:

import time, progress.bar

bar = progress.bar.Bar(
          suffix = '%(index)d of %(max)d (%(percent)d%%)  '
                   'eta: %(eta_td)s  time elapsed: %(elapsed_td)s',
      max = 100)

for index in range(100):
    bar.next()
    time.sleep(0.1)

bar.finish()

This is the output on a 87x40 terminal (the bug "starts" at value 10):

 |###                             | 10 of 100 (10%)  eta: 0:00:09  time elapsed: 0:00:0
 |###                             | 11 of 100 (11%)  eta: 0:00:09  time elapsed: 0:00:0
 |###                             | 12 of 100 (12%)  eta: 0:00:09  time elapsed: 0:00:0
 |####                            | 13 of 100 (13%)  eta: 0:00:09  time elapsed: 0:00:0
 |####                            | 14 of 100 (14%)  eta: 0:00:09  time elapsed: 0:00:0
 |####                            | 15 of 100 (15%)  eta: 0:00:09  time elapsed: 0:00:0
 |#####                           | 16 of 100 (16%)  eta: 0:00:09  time elapsed: 0:00:0
 |#####                           | 17 of 100 (17%)  eta: 0:00:09  time elapsed: 0:00:0
 |#####                           | 18 of 100 (18%)  eta: 0:00:09  time elapsed: 0:00:0
 |######                          | 19 of 100 (19%)  eta: 0:00:09  time elapsed: 0:00:0
 |######                          | 20 of 100 (20%)  eta: 0:00:09  time elapsed: 0:00:0
 |######                          | 21 of 100 (21%)  eta: 0:00:08  time elapsed: 0:00:0
 |#######                         | 22 of 100 (22%)  eta: 0:00:08  time elapsed: 0:00:0
 |#######                         | 23 of 100 (23%)  eta: 0:00:08  time elapsed: 0:00:0
 |#######                         | 24 of 100 (24%)  eta: 0:00:08  time elapsed: 0:00:0
 |########                        | 25 of 100 (25%)  eta: 0:00:08  time elapsed: 0:00:0
 |########                        | 26 of 100 (26%)  eta: 0:00:08  time elapsed: 0:00:0
 |########                        | 27 of 100 (27%)  eta: 0:00:08  time elapsed: 0:00:0
 |########                        | 28 of 100 (28%)  eta: 0:00:08  time elapsed: 0:00:0
 |#########                       | 29 of 100 (28%)  eta: 0:00:08  time elapsed: 0:00:0
 |#########                       | 30 of 100 (30%)  eta: 0:00:08  time elapsed: 0:00:0
 |#########                       | 31 of 100 (31%)  eta: 0:00:07  time elapsed: 0:00:0
3
[...]

This is the output on a maximized terminal:

 |################################| 100 of 100 (100%)  eta: 0:00:00  time elapsed: 0:00:09
@shannonfenn
Copy link

So the root cause is how carriage return behaves after the terminal autowraps.

The simple solution I went with was to overload writeln() to wrap the printed line in escapes to disable and then re-enable autowrap:

    print('\x1b[?7l' + line + '\x1b[?7h', end='', file=self.file)

This however had the undesirable side-effect of truncating the line in a non-obvious way (fine as an individual fix, but not for default behaviour).

Options that I'd imagine would be nicer:

  • An 'auto' or max width option which would query terminal width when constructing the line in update() methods and use something like terminal_width - len(''.join([message, self.bar_prefix, self.bar_suffix, suffix])) to set the bar width for that update. This would resulting in fluctuating bar widths though due to changing suffices etc (which is why the original issue only started at the tenth iteration).
  • Changing the line clearing operations to instead save and restore the cursor position although:
    • I'm not sure the impact this would have on the clearing of intermediate lines, and
    • I have no idea how widely supported the save/restore escape sequences are.

@thomasjm
Copy link

@shannonfenn truncating the line sounds better as a default behavior then the terminal going crazy and emitting lots of progress bar lines.

I was investigating the effect this bug has on pip and found it is probably the root cause of issues like pypa/pip#6101. Along with affecting anyone who tries to use pip install on a small terminal :)

Is there some way I can help push this towards a fix?

@arigit
Copy link

arigit commented May 24, 2024

facing the same issue in Termux (android / smartphone terminal), noticed that depending on the terminal size the "newline" bug appears.

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

No branches or pull requests

4 participants