python-progressbar
python-progressbar copied to clipboard
OSError exception from AbsoluteETA on Windows CPython
Description
A progressbar containing an AbsoluteETA widget intermittently crashes with an OSError on Windows CPython.
Code
File "R:\downloadImages\downloadImages.py", line 246, in update
self.bar.update(self.alreadyCopied)
File "R:\python-progressbar\progressbar\bar.py", line 909, in update
self.start()
File "R:\python-progressbar\progressbar\bar.py", line 1012, in start
self.update(self.min_value, force=True)
File "R:\python-progressbar\progressbar\bar.py", line 940, in update
self._update_parents(value)
File "R:\python-progressbar\progressbar\bar.py", line 959, in _update_parents
StdRedirectMixin.update(self, value=value) # type: ignore
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "R:\python-progressbar\progressbar\bar.py", line 462, in update
DefaultFdMixin.update(self, value=value)
File "R:\python-progressbar\progressbar\bar.py", line 305, in update
line: str = converters.to_unicode(self._format_line())
^^^^^^^^^^^^^^^^^^^
File "R:\python-progressbar\progressbar\bar.py", line 336, in _format_line
widgets = ''.join(self._to_unicode(self._format_widgets()))
^^^^^^^^^^^^^^^^^^^^^^
File "R:\python-progressbar\progressbar\bar.py", line 362, in _format_widgets
widget_output = converters.to_unicode(widget(self, data))
^^^^^^^^^^^^^^^^^^
File "R:\python-progressbar\progressbar\widgets.py", line 564, in __call__
data['eta'] = utils.format_time(data['eta_seconds'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\jwd\AppData\Local\Programs\Python\Python312\Lib\site-packages\python_utils\time.py", line 124, in format_time
seconds = timestamp.timestamp()
^^^^^^^^^^^^^^^^^^^^^
Versions
CPython 3.12.3, Windows 11, progressbar 4.4.2.
Problem is not reproducible with CPython on current MacOS and Linux distributions. (C Library-dependent--see below)
Analysis
The datetime.timestamp() implementation on Windows CPython raises OSError when it's called on a very large datetime:
>>> from datetime import datetime
>>> dt = datetime.strptime("8362-03-01 09:53:14", "%Y-%m-%d %H:%M:%S")
>>> dt.timestamp()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument
This can happen if the initialization of data['elapsed'] at bar.py:758 comes up with a small non-zero value. (The cases I've seen are all values of 1 us.) The results of that calculation vary with CPU contention, etc., thus making the problem intermittent.
I've successfully tested a fix of adding OSError to the contextlib.suppress() call at widgets.py:547. However, I've been unable to craft a test that triggers the problem. Will you accept a pull request anyway?
Even without a test it would still be useful to have this fixed, thank you for the research!