python-progressbar
python-progressbar copied to clipboard
FormatCustomText not updated
Description
I've modified the format_custom_text example to use a with... as... context. The progress bar does not update when I do that, and I can't quite figure out why
Code
def format_custom_text():
format_custom_text = progressbar.FormatCustomText(
'Spam: %(spam).1f kg, eggs: %(eggs)d',
dict(
spam=0.25,
eggs=3,
),
)
with progressbar.ProgressBar(widgets=[
format_custom_text,
' :: ',
progressbar.Percentage(),
]).start() as bar:
for i in range(25):
format_custom_text.update_mapping(eggs=i * 2)
time.sleep(0.1)
The output only updates at the end, to show:
Spam: 0.2 kg, eggs: 48 :: N/A%
I also tried with adding a bar.update() after the last line within the loop, but with no success
Versions
- Python version: 3.9
- Operating System: Mac OS X
- Package version: 4.0.0
I've also tried:
format_custom_text = progressbar.FormatCustomText(
'Spam: %(spam).1f kg, eggs: %(eggs)d',
dict(
spam=0.25,
eggs=3,
),
)
bar = progressbar.ProgressBar(widgets=[format_custom_text])
bar.start()
for i in range(25):
format_custom_text.update_mapping(eggs=i * 2)
time.sleep(0.1)
bar.update(i)
The issue is that the progressbar is optimized for speed and it doesn't notice a big enough change.
By default it will update either:
- When the update would be visible in a bar (i.e. on a 80 character screen, if 1 character has changed)
- when a timed widget has reached its update interval
Note that a bar needs a maximum value to be able to calculate the width so the progressbar cannot know this in your case as you haven't specified the maximum value. Since neither of those widgets is timed, that isn't an option either.
Luckily, we have a simple workaround for this, just tell the progressbar to update every 0.1 second (or more often if you wish):
import time
import progressbar
format_custom_text = progressbar.FormatCustomText(
'Spam: %(spam).1f kg, eggs: %(eggs)d',
dict(
spam=0.25,
eggs=3,
),
)
with progressbar.ProgressBar(
poll_interval=0.1,
widgets=[
format_custom_text,
' :: ',
progressbar.Percentage(),
],
) as bar:
for i in bar(range(25)):
format_custom_text.update_mapping(eggs=i * 2)
time.sleep(0.1)