diff --git a/tqdm/std.py b/tqdm/std.py index b5ff064ed..fe74b6bef 100644 --- a/tqdm/std.py +++ b/tqdm/std.py @@ -771,11 +771,11 @@ def wrapper(*args, **kwargs): def __init__(self, iterable=None, desc=None, total=None, leave=True, file=None, ncols=None, mininterval=0.1, maxinterval=10.0, - miniters=None, ascii=None, disable=False, unit='it', - unit_scale=False, dynamic_ncols=False, smoothing=0.3, - bar_format=None, initial=0, position=None, postfix=None, - unit_divisor=1000, write_bytes=None, lock_args=None, - gui=False, **kwargs): + miniters=None, waituntil=0.0, ascii=None, disable=False, + unit='it', unit_scale=False, dynamic_ncols=False, + smoothing=0.3, bar_format=None, initial=0, position=None, + postfix=None, unit_divisor=1000, write_bytes=None, + lock_args=None, gui=False, **kwargs): """ Parameters ---------- @@ -821,6 +821,9 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True, Tweak this and `mininterval` to get very efficient loops. If your progress is erratic with both fast and slow iterations (network, skipping items, etc) you should set miniters=1. + waituntil : float, optional + Don't display the progressbar until this number [default: 0] of + seconds has elapsed. ascii : bool or str, optional If unspecified or False, use unicode (smooth blocks) to fill the meter. The fallback is to use ASCII characters " 123456789#". @@ -976,6 +979,7 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True, self.maxinterval = maxinterval self.miniters = miniters self.dynamic_miniters = dynamic_miniters + self.waituntil = waituntil self.ascii = ascii self.disable = disable self.unit = unit @@ -1010,7 +1014,8 @@ def __init__(self, iterable=None, desc=None, total=None, leave=True, if not gui: # Initialize the screen printer self.sp = self.status_printer(self.fp) - self.refresh(lock_args=self.lock_args) + if waituntil <= 0: + self.refresh(lock_args=self.lock_args) # Init the time counter self.last_print_t = self._time() @@ -1077,6 +1082,7 @@ def __iter__(self): dynamic_miniters = self.dynamic_miniters last_print_t = self.last_print_t last_print_n = self.last_print_n + start_t = self.start_t n = self.n smoothing = self.smoothing avg_time = self.avg_time @@ -1096,9 +1102,9 @@ def __iter__(self): # check counter first to avoid calls to time() if n - last_print_n >= self.miniters: miniters = self.miniters # watch monitoring thread changes - delta_t = time() - last_print_t - if delta_t >= mininterval: - cur_t = time() + cur_t = time() + delta_t = cur_t - last_print_t + if delta_t >= mininterval and cur_t - start_t >= self.waituntil: delta_it = n - last_print_n # EMA (not just overall average) if smoothing and delta_t and delta_it: @@ -1173,9 +1179,10 @@ def update(self, n=1): # check counter first to reduce calls to time() if self.n - self.last_print_n >= self.miniters: - delta_t = self._time() - self.last_print_t - if delta_t >= self.mininterval: - cur_t = self._time() + cur_t = self._time() + delta_t = cur_t - self.last_print_t + if (delta_t >= self.mininterval + and cur_t - self.start_t >= self.waituntil): delta_it = self.n - self.last_print_n # >= n # elapsed = cur_t - self.start_t # EMA (not just overall average) @@ -1248,15 +1255,17 @@ def fp_write(s): leave = pos == 0 if self.leave is None else self.leave with self._lock: - if leave: - # stats for overall rate (no weighted average) - self.avg_time = None - self.display(pos=0) - fp_write('\n') - else: - self.display(msg='', pos=pos) - if not pos: - fp_write('\r') + # If the following doesn't hold, we haven't even printed anything. + if self.last_print_t - self.start_t >= self.waituntil: + if leave: + # stats for overall rate (no weighted average) + self.avg_time = None + self.display(pos=0) + fp_write('\n') + else: + self.display(msg='', pos=pos) + if not pos: + fp_write('\r') def clear(self, nolock=False): """Clear current bar display.""" diff --git a/tqdm/tests/tests_tqdm.py b/tqdm/tests/tests_tqdm.py index 2ce4620a9..f2fc56ab5 100644 --- a/tqdm/tests/tests_tqdm.py +++ b/tqdm/tests/tests_tqdm.py @@ -610,6 +610,22 @@ def test_max_interval(): t2.close() +@with_setup(pretest, posttest) +def test_waituntil(): + """Test waituntil""" + timer = DiscreteTimer() + with closing(StringIO()) as our_file: + t = tqdm(total=2, file=our_file, leave=True, waituntil=3) + cpu_timify(t, timer) + timer.sleep(2) + t.update(1) + assert not our_file.getvalue() + timer.sleep(2) + t.update(1) + assert our_file.getvalue() + t.close() + + @with_setup(pretest, posttest) def test_min_iters(): """Test miniters"""