Skip to content

Commit 59b3cb2

Browse files
committed
refactor(widgets): dedup ETA value/elapsed + make UnknownLength explicit
ETA.__call__ and SmoothingETA.__call__ shared an identical value/elapsed default-resolution preamble. Extract it into ETA._resolve_value_elapsed() and call it from both; the shared helper's branches are covered by the ETA paths so SmoothingETA no longer needs its two '# pragma: no branch'. Also replace the TypeError-as-control-flow around _calculate_eta with an explicit 'progress.max_value is base.UnknownLength' check. The only source of that TypeError was subtracting the value from the UnknownLength sentinel inside _calculate_eta's 'if elapsed:' branch, so the explicit check is guarded by 'elapsed' too: this keeps the elapsed==0 case returning 0 (format_zero) instead of N/A, preserving byte-identical output. Nothing else in the ETA math raises TypeError, so the try/except is removed entirely rather than kept as a defensive handler. Behavior-preserving: full suite + render goldens unchanged, widgets.py at 100% branch coverage.
1 parent 3aaf461 commit 59b3cb2

1 file changed

Lines changed: 36 additions & 18 deletions

File tree

‎progressbar/widgets.py‎

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -569,33 +569,56 @@ def _calculate_eta(
569569
else:
570570
return 0
571571

572-
def __call__(
572+
def _resolve_value_elapsed(
573573
self,
574574
progress: ProgressBarMixinBase,
575575
data: Data,
576-
value=None,
577-
elapsed=None,
576+
value,
577+
elapsed,
578578
):
579-
"""Updates the widget to show the ETA or total time when finished."""
579+
"""Fill in the value/elapsed defaults shared by the ETA variants.
580+
581+
When a caller does not supply them, the per-item rate is based on the
582+
progress relative to ``min_value`` (not the raw value) and the elapsed
583+
time is taken from the data snapshot.
584+
"""
580585
if value is None:
581-
# The per-item rate must be based on the progress relative to
582-
# min_value, not the raw value
583586
value = data['value'] - progress.min_value
584587

585588
if elapsed is None:
586589
elapsed = data['time_elapsed']
587590

591+
return value, elapsed
592+
593+
def __call__(
594+
self,
595+
progress: ProgressBarMixinBase,
596+
data: Data,
597+
value=None,
598+
elapsed=None,
599+
):
600+
"""Updates the widget to show the ETA or total time when finished."""
601+
value, elapsed = self._resolve_value_elapsed(
602+
progress, data, value, elapsed
603+
)
604+
605+
# ``max_value`` is ``UnknownLength`` for indeterminate bars. The
606+
# remaining-count subtraction in ``_calculate_eta`` only runs (and
607+
# only then fails) once ``elapsed`` is truthy, so guard on both to
608+
# keep the ``elapsed == 0`` case rendering ``format_zero`` as before.
609+
# Nothing else in the ETA math raises ``TypeError``, so the previous
610+
# try/except-as-control-flow is intentionally removed.
588611
eta_na = False
589-
try:
612+
if elapsed and progress.max_value is base.UnknownLength:
613+
data['eta_seconds'] = None
614+
eta_na = True
615+
else:
590616
data['eta_seconds'] = self._calculate_eta(
591617
progress,
592618
data,
593619
value=value,
594620
elapsed=elapsed,
595621
)
596-
except TypeError:
597-
data['eta_seconds'] = None
598-
eta_na = True
599622

600623
data['eta'] = None
601624
if data['eta_seconds']:
@@ -722,14 +745,9 @@ def __call__(
722745
value=None,
723746
elapsed=None,
724747
):
725-
if value is None: # pragma: no branch
726-
# The per-item rate must be based on the progress relative to
727-
# min_value, not the raw value
728-
value = data['value'] - progress.min_value
729-
730-
if elapsed is None: # pragma: no branch
731-
elapsed = data['time_elapsed']
732-
748+
value, elapsed = self._resolve_value_elapsed(
749+
progress, data, value, elapsed
750+
)
733751
value = self.smoothing_algorithm.update(value, elapsed)
734752
return ETA.__call__(self, progress, data, value=value, elapsed=elapsed)
735753

0 commit comments

Comments
 (0)