Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/tqdm/std.py: 17%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

697 statements  

1""" 

2Customisable progressbar decorator for iterators. 

3Includes a default `range` iterator printing to `stderr`. 

4 

5Usage: 

6>>> from tqdm import trange, tqdm 

7>>> for i in trange(10): 

8... ... 

9""" 

10import sys 

11from collections import OrderedDict, defaultdict 

12from contextlib import contextmanager 

13from datetime import datetime, timedelta, timezone 

14from numbers import Number 

15from time import time 

16from warnings import warn 

17from weakref import WeakSet 

18 

19from ._monitor import TMonitor 

20from .utils import ( 

21 CallbackIOWrapper, Comparable, DisableOnWriteError, FormatReplace, SimpleTextIOWrapper, 

22 _is_ascii, _screen_shape_wrapper, _supports_unicode, _term_move_up, disp_len, disp_trim, 

23 envwrap) 

24 

25__author__ = "https://github.com/tqdm/tqdm#contributions" 

26__all__ = ['tqdm', 'trange', 

27 'TqdmTypeError', 'TqdmKeyError', 'TqdmWarning', 

28 'TqdmExperimentalWarning', 'TqdmDeprecationWarning', 

29 'TqdmMonitorWarning'] 

30 

31 

32class TqdmTypeError(TypeError): 

33 pass 

34 

35 

36class TqdmKeyError(KeyError): 

37 pass 

38 

39 

40class TqdmWarning(Warning): 

41 """base class for all tqdm warnings. 

42 

43 Used for non-external-code-breaking errors, such as garbled printing. 

44 """ 

45 def __init__(self, msg, fp_write=None, *a, **k): 

46 if fp_write is not None: 

47 fp_write("\n" + self.__class__.__name__ + ": " + str(msg).rstrip() + '\n') 

48 else: 

49 super().__init__(msg, *a, **k) 

50 

51 

52class TqdmExperimentalWarning(TqdmWarning, FutureWarning): 

53 """beta feature, unstable API and behaviour""" 

54 pass 

55 

56 

57class TqdmDeprecationWarning(TqdmWarning, DeprecationWarning): 

58 # not suppressed if raised 

59 pass 

60 

61 

62class TqdmMonitorWarning(TqdmWarning, RuntimeWarning): 

63 """tqdm monitor errors which do not affect external functionality""" 

64 pass 

65 

66 

67def TRLock(*args, **kwargs): 

68 """threading RLock""" 

69 try: 

70 from threading import RLock 

71 return RLock(*args, **kwargs) 

72 except (ImportError, OSError): # pragma: no cover 

73 pass 

74 

75 

76class TqdmDefaultWriteLock(object): 

77 """ 

78 Provide a default write lock for thread and multiprocessing safety. 

79 Works only on platforms supporting `fork` (so Windows is excluded). 

80 You must initialise a `tqdm` or `TqdmDefaultWriteLock` instance 

81 before forking in order for the write lock to work. 

82 On Windows, you need to supply the lock from the parent to the children as 

83 an argument to joblib or the parallelism lib you use. 

84 """ 

85 # global thread lock so no setup required for multithreading. 

86 # NB: Do not create multiprocessing lock as it sets the multiprocessing 

87 # context, disallowing `spawn()`/`forkserver()` 

88 th_lock = TRLock() 

89 

90 def __init__(self): 

91 # Create global parallelism locks to avoid racing issues with parallel 

92 # bars works only if fork available (Linux/MacOSX, but not Windows) 

93 cls = type(self) 

94 root_lock = cls.th_lock 

95 if root_lock is not None: 

96 root_lock.acquire() 

97 cls.create_mp_lock() 

98 self.locks = [lk for lk in [cls.mp_lock, cls.th_lock] if lk is not None] 

99 if root_lock is not None: 

100 root_lock.release() 

101 

102 def acquire(self, *a, **k): 

103 for lock in self.locks: 

104 lock.acquire(*a, **k) 

105 

106 def release(self): 

107 for lock in self.locks[::-1]: # Release in inverse order of acquisition 

108 lock.release() 

109 

110 def __enter__(self): 

111 self.acquire() 

112 

113 def __exit__(self, *exc): 

114 self.release() 

115 

116 @classmethod 

117 def create_mp_lock(cls): 

118 if not hasattr(cls, 'mp_lock'): 

119 try: 

120 from multiprocessing import RLock 

121 cls.mp_lock = RLock() 

122 except (ImportError, OSError): # pragma: no cover 

123 cls.mp_lock = None 

124 

125 @classmethod 

126 def create_th_lock(cls): 

127 assert hasattr(cls, 'th_lock') 

128 warn("create_th_lock not needed anymore", TqdmDeprecationWarning, stacklevel=2) 

129 

130 

131class Bar(object): 

132 """ 

133 `str.format`-able bar with format specifiers: `[width][type]` 

134 

135 - `width` 

136 + unspecified (default): use `self.default_len` 

137 + `int >= 0`: overrides `self.default_len` 

138 + `int < 0`: subtract from `self.default_len` 

139 - `type` 

140 + `a`: ascii (`charset=self.ASCII` override) 

141 + `u`: unicode (`charset=self.UTF` override) 

142 + `b`: blank (`charset=" "` override) 

143 """ 

144 ASCII = " 123456789#" 

145 UTF = u" " + u''.join(map(chr, range(0x258F, 0x2587, -1))) 

146 BLANK = " " 

147 COLOUR_RESET = '\x1b[0m' 

148 COLOUR_RGB = '\x1b[38;2;%d;%d;%dm' 

149 COLOURS = {'BLACK': '\x1b[30m', 'RED': '\x1b[31m', 'GREEN': '\x1b[32m', 

150 'YELLOW': '\x1b[33m', 'BLUE': '\x1b[34m', 'MAGENTA': '\x1b[35m', 

151 'CYAN': '\x1b[36m', 'WHITE': '\x1b[37m'} 

152 

153 def __init__(self, frac, default_len=10, charset=UTF, colour=None): 

154 if not 0 <= frac <= 1: 

155 warn("clamping frac to range [0, 1]", TqdmWarning, stacklevel=2) 

156 frac = max(0, min(1, frac)) 

157 assert default_len > 0 

158 self.frac = frac 

159 self.default_len = default_len 

160 self.charset = charset 

161 self.colour = colour 

162 

163 @property 

164 def colour(self): 

165 return self._colour 

166 

167 @colour.setter 

168 def colour(self, value): 

169 if not value: 

170 self._colour = None 

171 return 

172 try: 

173 if value.upper() in self.COLOURS: 

174 self._colour = self.COLOURS[value.upper()] 

175 elif value[0] == '#' and len(value) == 7: 

176 self._colour = self.COLOUR_RGB % tuple( 

177 int(i, 16) for i in (value[1:3], value[3:5], value[5:7])) 

178 else: 

179 raise KeyError 

180 except (KeyError, AttributeError): 

181 warn("Unknown colour (%s); valid choices: [hex (#00ff00), %s]" % ( 

182 value, ", ".join(self.COLOURS)), 

183 TqdmWarning, stacklevel=2) 

184 self._colour = None 

185 

186 def __format__(self, format_spec): 

187 if format_spec: 

188 _type = format_spec[-1].lower() 

189 try: 

190 charset = {'a': self.ASCII, 'u': self.UTF, 'b': self.BLANK}[_type] 

191 except KeyError: 

192 charset = self.charset 

193 else: 

194 format_spec = format_spec[:-1] 

195 if format_spec: 

196 N_BARS = int(format_spec) 

197 if N_BARS < 0: 

198 N_BARS += self.default_len 

199 else: 

200 N_BARS = self.default_len 

201 else: 

202 charset = self.charset 

203 N_BARS = self.default_len 

204 

205 nsyms = len(charset) - 1 

206 bar_length, frac_bar_length = divmod(int(self.frac * N_BARS * nsyms), nsyms) 

207 

208 res = charset[-1] * bar_length 

209 if bar_length < N_BARS: # whitespace padding 

210 res = res + charset[frac_bar_length] + charset[0] * (N_BARS - bar_length - 1) 

211 return self.colour + res + self.COLOUR_RESET if self.colour else res 

212 

213 

214class EMA(object): 

215 """ 

216 Exponential moving average: smoothing to give progressively lower 

217 weights to older values. 

218 

219 Parameters 

220 ---------- 

221 smoothing : float, optional 

222 Smoothing factor in range [0, 1], [default: 0.3]. 

223 Increase to give more weight to recent values. 

224 Ranges from 0 (yields old value) to 1 (yields new value). 

225 """ 

226 def __init__(self, smoothing=0.3): 

227 self.alpha = smoothing 

228 self.last = 0 

229 self.calls = 0 

230 

231 def __call__(self, x=None): 

232 """ 

233 Parameters 

234 ---------- 

235 x : float 

236 New value to include in EMA. 

237 """ 

238 beta = 1 - self.alpha 

239 if x is not None: 

240 self.last = self.alpha * x + beta * self.last 

241 self.calls += 1 

242 return self.last / (1 - beta ** self.calls) if self.calls else self.last 

243 

244 

245class tqdm(Comparable): 

246 """ 

247 Decorate an iterable object, returning an iterator which acts exactly 

248 like the original iterable, but prints a dynamically updating 

249 progressbar every time a value is requested. 

250 

251 Parameters 

252 ---------- 

253 iterable : iterable, optional 

254 Iterable to decorate with a progressbar. 

255 Leave blank to manually manage the updates. 

256 desc : str, optional 

257 Prefix for the progressbar. 

258 total : int or float, optional 

259 The number of expected iterations. If unspecified, 

260 len(iterable) is used if possible. If float("inf") or as a last 

261 resort, only basic progress statistics are displayed 

262 (no ETA, no progressbar). 

263 If `gui` is True and this parameter needs subsequent updating, 

264 specify an initial arbitrary large positive number, 

265 e.g. 9e9. 

266 leave : bool, optional 

267 If [default: True], keeps all traces of the progressbar 

268 upon termination of iteration. 

269 If `None`, will leave only if `position` is `0`. 

270 file : `io.TextIOWrapper` or `io.StringIO`, optional 

271 Specifies where to output the progress messages 

272 (default: sys.stderr). Uses `file.write(str)` and `file.flush()` 

273 methods. For encoding, see `write_bytes`. 

274 ncols : int, optional 

275 The width of the entire output message. If specified, 

276 dynamically resizes the progressbar to stay within this bound. 

277 If unspecified, attempts to use environment width. The 

278 fallback is a meter width of 10 and no limit for the counter and 

279 statistics. If 0, will not print any meter (only stats). 

280 mininterval : float, optional 

281 Minimum progress display update interval [default: 0.1] seconds. 

282 maxinterval : float, optional 

283 Maximum progress display update interval [default: 10] seconds. 

284 Automatically adjusts `miniters` to correspond to `mininterval` 

285 after long display update lag. Only works if `dynamic_miniters` 

286 or monitor thread is enabled. 

287 miniters : int or float, optional 

288 Minimum progress display update interval, in iterations. 

289 If 0 and `dynamic_miniters`, will automatically adjust to equal 

290 `mininterval` (more CPU efficient, good for tight loops). 

291 If > 0, will skip display of specified number of iterations. 

292 Tweak this and `mininterval` to get very efficient loops. 

293 If your progress is erratic with both fast and slow iterations 

294 (network, skipping items, etc) you should set miniters=1. 

295 ascii : bool or str, optional 

296 If unspecified or False, use unicode (smooth blocks) to fill 

297 the meter. The fallback is to use ASCII characters " 123456789#". 

298 disable : bool, optional 

299 Whether to disable the entire progressbar wrapper 

300 [default: False]. If set to None, disable on non-TTY. 

301 unit : str, optional 

302 String that will be used to define the unit of each iteration 

303 [default: it]. 

304 unit_scale : bool or int or float, optional 

305 If 1 or True, the number of iterations will be reduced/scaled 

306 automatically and a metric prefix following the 

307 International System of Units standard will be added 

308 (kilo, mega, etc.) [default: False]. If any other non-zero 

309 number, will scale `total` and `n`. 

310 dynamic_ncols : bool, optional 

311 If set, constantly alters `ncols` and `nrows` to the 

312 environment (allowing for window resizes) [default: False]. 

313 smoothing : float, optional 

314 Exponential moving average smoothing factor for speed estimates 

315 (ignored in GUI mode). Ranges from 0 (average speed) to 1 

316 (current/instantaneous speed) [default: 0.3]. 

317 bar_format : str, optional 

318 Specify a custom bar string formatting. May impact performance. 

319 [default: '{l_bar}{bar}{r_bar}'], where 

320 l_bar='{desc}: {percentage:3.0f}%|' and 

321 r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, ' 

322 '{rate_fmt}{postfix}]' 

323 Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt, 

324 percentage, elapsed, elapsed_s, ncols, nrows, desc, unit, 

325 rate, rate_fmt, rate_noinv, rate_noinv_fmt, 

326 rate_inv, rate_inv_fmt, postfix, unit_divisor, 

327 remaining, remaining_s, eta. 

328 Note that a trailing ": " is automatically removed after {desc} 

329 if the latter is empty. 

330 initial : int or float, optional 

331 The initial counter value. Useful when restarting a progress 

332 bar [default: 0]. If using float, consider specifying `{n:.3f}` 

333 or similar in `bar_format`, or specifying `unit_scale`. 

334 position : int, optional 

335 Specify the line offset to print this bar (starting from 0) 

336 Automatic if unspecified. 

337 Useful to manage multiple bars at once (eg, from threads). 

338 postfix : dict or *, optional 

339 Specify additional stats to display at the end of the bar. 

340 Calls `set_postfix(**postfix)` if possible (dict). 

341 unit_divisor : float, optional 

342 [default: 1000], ignored unless `unit_scale` is True. 

343 write_bytes : bool, optional 

344 Whether to write bytes. If (default: False) will write unicode. 

345 lock_args : tuple, optional 

346 Passed to `refresh` for intermediate output 

347 (initialisation, iterating, and updating). 

348 nrows : int, optional 

349 The screen height. If specified, hides nested bars outside this 

350 bound. If unspecified, attempts to use environment height. 

351 The fallback is 20. 

352 colour : str, optional 

353 Bar colour (e.g. 'green', '#00ff00'). 

354 delay : float, optional 

355 Don't display until [default: 0] seconds have elapsed. 

356 gui : bool, optional 

357 WARNING: internal parameter - do not use. 

358 Use tqdm.gui.tqdm(...) instead. If set, will attempt to use 

359 matplotlib animations for a graphical output [default: False]. 

360 

361 Returns 

362 ------- 

363 out : decorated iterator. 

364 """ 

365 

366 monitor_interval = 10 # set to 0 to disable the thread 

367 monitor = None 

368 _instances = WeakSet() 

369 

370 @staticmethod 

371 def format_sizeof(num, suffix='', divisor=1000): 

372 """ 

373 Formats a number (greater than unity) with SI Order of Magnitude 

374 prefixes. 

375 

376 Parameters 

377 ---------- 

378 num : float 

379 Number ( >= 1) to format. 

380 suffix : str, optional 

381 Post-postfix [default: '']. 

382 divisor : float, optional 

383 Divisor between prefixes [default: 1000]. 

384 

385 Returns 

386 ------- 

387 out : str 

388 Number with Order of Magnitude SI unit postfix. 

389 """ 

390 for unit in ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z']: 

391 if abs(num) < 999.5: 

392 if abs(num) < 99.95: 

393 if abs(num) < 9.995: 

394 return f'{num:1.2f}{unit}{suffix}' 

395 return f'{num:2.1f}{unit}{suffix}' 

396 return f'{num:3.0f}{unit}{suffix}' 

397 num /= divisor 

398 return f'{num:3.1f}Y{suffix}' 

399 

400 @staticmethod 

401 def format_interval(t): 

402 """ 

403 Formats a number of seconds as a clock time, [H:]MM:SS 

404 

405 Parameters 

406 ---------- 

407 t : int 

408 Number of seconds. 

409 

410 Returns 

411 ------- 

412 out : str 

413 [H:]MM:SS 

414 """ 

415 mins, s = divmod(int(t), 60) 

416 h, m = divmod(mins, 60) 

417 return f'{h:d}:{m:02d}:{s:02d}' if h else f'{m:02d}:{s:02d}' 

418 

419 @staticmethod 

420 def format_num(n): 

421 """ 

422 Intelligent scientific notation (.3g). 

423 

424 Parameters 

425 ---------- 

426 n : int or float or Numeric 

427 A Number. 

428 

429 Returns 

430 ------- 

431 out : str 

432 Formatted number. 

433 """ 

434 f = f'{n:.3g}'.replace('e+0', 'e+').replace('e-0', 'e-') 

435 n = str(n) 

436 return f if len(f) < len(n) else n 

437 

438 @staticmethod 

439 def status_printer(file): 

440 """ 

441 Manage the printing and in-place updating of a line of characters. 

442 Note that if the string is longer than a line, then in-place 

443 updating may not work (it will print a new line at each refresh). 

444 """ 

445 fp = file 

446 fp_flush = getattr(fp, 'flush', lambda: None) # pragma: no cover 

447 if fp in (sys.stderr, sys.stdout): 

448 getattr(sys.stderr, 'flush', lambda: None)() 

449 getattr(sys.stdout, 'flush', lambda: None)() 

450 

451 def fp_write(s): 

452 fp.write(str(s)) 

453 fp_flush() 

454 

455 last_len = [0] 

456 

457 def print_status(s): 

458 len_s = disp_len(s) 

459 fp_write('\r' + s + (' ' * max(last_len[0] - len_s, 0))) 

460 last_len[0] = len_s 

461 

462 return print_status 

463 

464 @staticmethod 

465 def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False, unit='it', 

466 unit_scale=False, rate=None, bar_format=None, postfix=None, 

467 unit_divisor=1000, initial=0, colour=None, **extra_kwargs): 

468 """ 

469 Return a string-based progress bar given some parameters 

470 

471 Parameters 

472 ---------- 

473 n : int or float 

474 Number of finished iterations. 

475 total : int or float 

476 The expected total number of iterations. If meaningless (None), 

477 only basic progress statistics are displayed (no ETA). 

478 elapsed : float 

479 Number of seconds passed since start. 

480 ncols : int, optional 

481 The width of the entire output message. If specified, 

482 dynamically resizes `{bar}` to stay within this bound 

483 [default: None]. If `0`, will not print any bar (only stats). 

484 The fallback is `{bar:10}`. 

485 prefix : str, optional 

486 Prefix message (included in total width) [default: '']. 

487 Use as {desc} in bar_format string. 

488 ascii : bool, optional or str, optional 

489 If not set, use unicode (smooth blocks) to fill the meter 

490 [default: False]. The fallback is to use ASCII characters 

491 " 123456789#". 

492 unit : str, optional 

493 The iteration unit [default: 'it']. 

494 unit_scale : bool or int or float, optional 

495 If 1 or True, the number of iterations will be printed with an 

496 appropriate SI metric prefix (k = 10^3, M = 10^6, etc.) 

497 [default: False]. If any other non-zero number, will scale 

498 `total` and `n`. 

499 rate : float, optional 

500 Manual override for iteration rate. 

501 If [default: None], uses n/elapsed. 

502 bar_format : str, optional 

503 Specify a custom bar string formatting. May impact performance. 

504 [default: '{l_bar}{bar}{r_bar}'], where 

505 l_bar='{desc}: {percentage:3.0f}%|' and 

506 r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, ' 

507 '{rate_fmt}{postfix}]' 

508 Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt, 

509 percentage, elapsed, elapsed_s, ncols, nrows, desc, unit, 

510 rate, rate_fmt, rate_noinv, rate_noinv_fmt, 

511 rate_inv, rate_inv_fmt, postfix, unit_divisor, 

512 remaining, remaining_s, eta. 

513 Note that a trailing ": " is automatically removed after {desc} 

514 if the latter is empty. 

515 postfix : *, optional 

516 Similar to `prefix`, but placed at the end 

517 (e.g. for additional stats). 

518 Note: postfix is usually a string (not a dict) for this method, 

519 and will if possible be set to postfix = ', ' + postfix. 

520 However other types are supported (#382). 

521 unit_divisor : float, optional 

522 [default: 1000], ignored unless `unit_scale` is True. 

523 initial : int or float, optional 

524 The initial counter value [default: 0]. 

525 colour : str, optional 

526 Bar colour (e.g. 'green', '#00ff00'). 

527 

528 Returns 

529 ------- 

530 out : Formatted meter and stats, ready to display. 

531 """ 

532 

533 # sanity check: total 

534 if total and n >= (total + 0.5): # allow float imprecision (#849) 

535 total = None 

536 

537 # apply custom scale if necessary 

538 if unit_scale and unit_scale not in (True, 1): 

539 if total: 

540 total *= unit_scale 

541 n *= unit_scale 

542 if rate: 

543 rate *= unit_scale # by default rate = self.avg_dn / self.avg_dt 

544 unit_scale = False 

545 

546 elapsed_str = tqdm.format_interval(elapsed) 

547 

548 # if unspecified, attempt to use rate = average speed 

549 # (we allow manual override since predicting time is an arcane art) 

550 if rate is None and elapsed: 

551 rate = (n - initial) / elapsed 

552 inv_rate = 1 / rate if rate else None 

553 format_sizeof = tqdm.format_sizeof 

554 rate_noinv_fmt = ((format_sizeof(rate) if unit_scale else f'{rate:5.2f}') 

555 if rate else '?') + unit + '/s' 

556 rate_inv_fmt = ( 

557 (format_sizeof(inv_rate) if unit_scale else f'{inv_rate:5.2f}') 

558 if inv_rate else '?') + 's/' + unit 

559 rate_fmt = rate_inv_fmt if inv_rate and inv_rate > 1 else rate_noinv_fmt 

560 

561 if unit_scale: 

562 n_fmt = format_sizeof(n, divisor=unit_divisor) 

563 total_fmt = format_sizeof(total, divisor=unit_divisor) if total is not None else '?' 

564 else: 

565 n_fmt = str(n) 

566 total_fmt = str(total) if total is not None else '?' 

567 

568 try: 

569 postfix = ', ' + postfix if postfix else '' 

570 except TypeError: 

571 pass 

572 

573 remaining = (total - n) / rate if rate and total else 0 

574 remaining_str = tqdm.format_interval(remaining) if rate else '?' 

575 try: 

576 eta_dt = (datetime.now() + timedelta(seconds=remaining) 

577 if rate and total else datetime.fromtimestamp(0, timezone.utc)) 

578 except OverflowError: 

579 eta_dt = datetime.max 

580 

581 # format the stats displayed to the left and right sides of the bar 

582 if prefix: 

583 # old prefix setup work around 

584 bool_prefix_colon_already = (prefix[-2:] == ": ") 

585 l_bar = prefix if bool_prefix_colon_already else prefix + ": " 

586 else: 

587 l_bar = '' 

588 

589 r_bar = f'| {n_fmt}/{total_fmt} [{elapsed_str}<{remaining_str}, {rate_fmt}{postfix}]' 

590 

591 # Custom bar formatting 

592 # Populate a dict with all available progress indicators 

593 format_dict = { 

594 # slight extension of self.format_dict 

595 'n': n, 'n_fmt': n_fmt, 'total': total, 'total_fmt': total_fmt, 

596 'elapsed': elapsed_str, 'elapsed_s': elapsed, 

597 'ncols': ncols, 'desc': prefix or '', 'unit': unit, 

598 'rate': inv_rate if inv_rate and inv_rate > 1 else rate, 

599 'rate_fmt': rate_fmt, 'rate_noinv': rate, 

600 'rate_noinv_fmt': rate_noinv_fmt, 'rate_inv': inv_rate, 

601 'rate_inv_fmt': rate_inv_fmt, 

602 'postfix': postfix, 'unit_divisor': unit_divisor, 

603 'colour': colour, 

604 # plus more useful definitions 

605 'remaining': remaining_str, 'remaining_s': remaining, 

606 'l_bar': l_bar, 'r_bar': r_bar, 'eta': eta_dt, 

607 **extra_kwargs} 

608 

609 # total is known: we can predict some stats 

610 if total: 

611 # fractional and percentage progress 

612 frac = n / total 

613 percentage = frac * 100 

614 

615 l_bar += f'{percentage:3.0f}%|' 

616 

617 if ncols == 0: 

618 return l_bar[:-1] + r_bar[1:] 

619 

620 format_dict.update(l_bar=l_bar) 

621 if bar_format: 

622 format_dict.update(percentage=percentage) 

623 

624 # auto-remove colon for empty `{desc}` 

625 if not prefix: 

626 bar_format = bar_format.replace("{desc}: ", '') 

627 else: 

628 bar_format = "{l_bar}{bar}{r_bar}" 

629 

630 full_bar = FormatReplace() 

631 nobar = bar_format.format(bar=full_bar, **format_dict) 

632 if not full_bar.format_called: 

633 return nobar # no `{bar}`; nothing else to do 

634 

635 # Formatting progress bar space available for bar's display 

636 full_bar = Bar(frac, 

637 max(1, ncols - disp_len(nobar)) if ncols else 10, 

638 charset=Bar.ASCII if ascii is True else ascii or Bar.UTF, 

639 colour=colour) 

640 if not _is_ascii(full_bar.charset) and _is_ascii(bar_format): 

641 bar_format = str(bar_format) 

642 res = bar_format.format(bar=full_bar, **format_dict) 

643 return disp_trim(res, ncols) if ncols else res 

644 

645 elif bar_format: 

646 # user-specified bar_format but no total 

647 l_bar += '|' 

648 format_dict.update(l_bar=l_bar, percentage=0) 

649 full_bar = FormatReplace() 

650 nobar = bar_format.format(bar=full_bar, **format_dict) 

651 if not full_bar.format_called: 

652 return nobar 

653 full_bar = Bar(0, 

654 max(1, ncols - disp_len(nobar)) if ncols else 10, 

655 charset=Bar.BLANK, colour=colour) 

656 res = bar_format.format(bar=full_bar, **format_dict) 

657 return disp_trim(res, ncols) if ncols else res 

658 else: 

659 # no total: no progressbar, ETA, just progress stats 

660 return (f'{(prefix + ": ") if prefix else ""}' 

661 f'{n_fmt}{unit} [{elapsed_str}, {rate_fmt}{postfix}]') 

662 

663 def __new__(cls, *_, **__): 

664 instance = object.__new__(cls) 

665 with cls.get_lock(): # also constructs lock if non-existent 

666 cls._instances.add(instance) 

667 # create monitoring thread 

668 if cls.monitor_interval and (cls.monitor is None 

669 or not cls.monitor.report()): 

670 try: 

671 cls.monitor = TMonitor(cls, cls.monitor_interval) 

672 except Exception as e: # pragma: nocover 

673 warn("tqdm:disabling monitor support" 

674 " (monitor_interval = 0) due to:\n" + str(e), 

675 TqdmMonitorWarning, stacklevel=2) 

676 cls.monitor_interval = 0 

677 return instance 

678 

679 @classmethod 

680 def _get_free_pos(cls, instance=None): 

681 """Skips specified instance.""" 

682 positions = {abs(inst.pos) for inst in cls._instances 

683 if inst is not instance and hasattr(inst, "pos")} 

684 return min(set(range(len(positions) + 1)).difference(positions)) 

685 

686 @classmethod 

687 def _decr_instances(cls, instance): 

688 """ 

689 Remove from list and reposition another unfixed bar 

690 to fill the new gap. 

691 

692 This means that by default (where all nested bars are unfixed), 

693 order is not maintained but screen flicker/blank space is minimised. 

694 (tqdm<=4.44.1 moved ALL subsequent unfixed bars up.) 

695 """ 

696 with cls._lock: 

697 try: 

698 cls._instances.remove(instance) 

699 except KeyError: 

700 # if not instance.gui: # pragma: no cover 

701 # raise 

702 pass # py2: maybe magically removed already 

703 # else: 

704 if not instance.gui: 

705 last = (instance.nrows or 20) - 1 

706 # find unfixed (`pos >= 0`) overflow (`pos >= nrows - 1`) 

707 instances = list(filter( 

708 lambda i: hasattr(i, "pos") and last <= i.pos, 

709 cls._instances)) 

710 # set first found to current `pos` 

711 if instances: 

712 inst = min(instances, key=lambda i: i.pos) 

713 inst.clear(nolock=True) 

714 inst.pos = abs(instance.pos) 

715 

716 @classmethod 

717 def write(cls, s, file=None, end="\n", nolock=False): 

718 """Print a message via tqdm (without overlap with bars).""" 

719 fp = file if file is not None else sys.stdout 

720 with cls.external_write_mode(file=file, nolock=nolock): 

721 # Write the message 

722 fp.write(s) 

723 fp.write(end) 

724 

725 @classmethod 

726 @contextmanager 

727 def external_write_mode(cls, file=None, nolock=False): 

728 """ 

729 Disable tqdm within context and refresh tqdm when exits. 

730 Useful when writing to standard output stream 

731 """ 

732 fp = file if file is not None else sys.stdout 

733 

734 try: 

735 if not nolock: 

736 cls.get_lock().acquire() 

737 # Clear all bars 

738 inst_cleared = [] 

739 for inst in getattr(cls, '_instances', []): 

740 # Clear instance if in the target output file 

741 # or if write output + tqdm output are both either 

742 # sys.stdout or sys.stderr (because both are mixed in terminal) 

743 if hasattr(inst, "start_t") and (inst.fp == fp or all( 

744 f in (sys.stdout, sys.stderr) for f in (fp, inst.fp))): 

745 inst.clear(nolock=True) 

746 inst_cleared.append(inst) 

747 yield 

748 # Force refresh display of bars we cleared 

749 for inst in inst_cleared: 

750 inst.refresh(nolock=True) 

751 finally: 

752 if not nolock: 

753 cls._lock.release() 

754 

755 @classmethod 

756 def set_lock(cls, lock): 

757 """Set the global lock.""" 

758 cls._lock = lock 

759 

760 @classmethod 

761 def get_lock(cls): 

762 """Get the global lock. Construct it if it does not exist.""" 

763 if not hasattr(cls, '_lock'): 

764 cls._lock = TqdmDefaultWriteLock() 

765 return cls._lock 

766 

767 @classmethod 

768 def pandas(cls, **tqdm_kwargs): 

769 """ 

770 Registers the current `tqdm` class with 

771 pandas.core. 

772 ( frame.DataFrame 

773 | series.Series 

774 | groupby.(generic.)DataFrameGroupBy 

775 | groupby.(generic.)SeriesGroupBy 

776 ).progress_apply 

777 

778 A new instance will be created every time `progress_apply` is called, 

779 and each instance will automatically `close()` upon completion. 

780 

781 Parameters 

782 ---------- 

783 tqdm_kwargs : arguments for the tqdm instance 

784 

785 Examples 

786 -------- 

787 >>> import pandas as pd 

788 >>> import numpy as np 

789 >>> from tqdm import tqdm 

790 >>> from tqdm.gui import tqdm as tqdm_gui 

791 >>> 

792 >>> df = pd.DataFrame(np.random.randint(0, 100, (100000, 6))) 

793 >>> tqdm.pandas(ncols=50) # can use tqdm_gui, optional kwargs, etc 

794 >>> # Now you can use `progress_apply` instead of `apply` 

795 >>> df.groupby(0).progress_apply(lambda x: x**2) 

796 

797 References 

798 ---------- 

799 <https://stackoverflow.com/questions/18603270/\ 

800 progress-indicator-during-pandas-operations-python> 

801 """ 

802 from warnings import catch_warnings, simplefilter 

803 

804 from pandas.core.frame import DataFrame 

805 from pandas.core.series import Series 

806 try: 

807 with catch_warnings(): 

808 simplefilter("ignore", category=FutureWarning) 

809 from pandas import Panel 

810 except ImportError: # pandas>=1.2.0 

811 Panel = None 

812 Rolling, Expanding = None, None 

813 try: # pandas>=1.0.0 

814 from pandas.core.window.rolling import _Rolling_and_Expanding 

815 except ImportError: 

816 try: # pandas>=0.18.0 

817 from pandas.core.window import _Rolling_and_Expanding 

818 except ImportError: # pandas>=1.2.0 

819 try: # pandas>=1.2.0 

820 from pandas.core.window.expanding import Expanding 

821 from pandas.core.window.rolling import Rolling 

822 _Rolling_and_Expanding = Rolling, Expanding 

823 except ImportError: # pragma: no cover 

824 _Rolling_and_Expanding = None 

825 try: # pandas>=0.25.0 

826 from pandas.core.groupby.generic import SeriesGroupBy # , NDFrameGroupBy 

827 from pandas.core.groupby.generic import DataFrameGroupBy 

828 except ImportError: # pragma: no cover 

829 try: # pandas>=0.23.0 

830 from pandas.core.groupby.groupby import DataFrameGroupBy, SeriesGroupBy 

831 except ImportError: 

832 from pandas.core.groupby import DataFrameGroupBy, SeriesGroupBy 

833 try: # pandas>=0.23.0 

834 from pandas.core.groupby.groupby import GroupBy 

835 except ImportError: # pragma: no cover 

836 from pandas.core.groupby import GroupBy 

837 

838 try: # pandas>=0.23.0 

839 from pandas.core.groupby.groupby import PanelGroupBy 

840 except ImportError: 

841 try: 

842 from pandas.core.groupby import PanelGroupBy 

843 except ImportError: # pandas>=0.25.0 

844 PanelGroupBy = None 

845 

846 tqdm_kwargs = tqdm_kwargs.copy() 

847 deprecated_t = [tqdm_kwargs.pop('deprecated_t', None)] 

848 

849 def inner_generator(df_function='apply'): 

850 def inner(df, func, *args, **kwargs): 

851 """ 

852 Parameters 

853 ---------- 

854 df : (DataFrame|Series)[GroupBy] 

855 Data (may be grouped). 

856 func : function 

857 To be applied on the (grouped) data. 

858 **kwargs : optional 

859 Transmitted to `df.apply()`. 

860 """ 

861 

862 # Precompute total iterations 

863 total = tqdm_kwargs.pop("total", getattr(df, 'ngroups', None)) 

864 if total is None: # not grouped 

865 if df_function == 'applymap': 

866 total = df.size 

867 elif isinstance(df, Series): 

868 total = len(df) 

869 elif (_Rolling_and_Expanding is None or 

870 not isinstance(df, _Rolling_and_Expanding)): 

871 # DataFrame or Panel 

872 axis = kwargs.get('axis', 0) 

873 if axis == 'index': 

874 axis = 0 

875 elif axis == 'columns': 

876 axis = 1 

877 # when axis=0, total is shape[axis1] 

878 total = df.size // df.shape[axis] 

879 

880 # Init bar 

881 if deprecated_t[0] is not None: 

882 t = deprecated_t[0] 

883 deprecated_t[0] = None 

884 else: 

885 t = cls(total=total, **tqdm_kwargs) 

886 

887 if len(args) > 0: 

888 # *args intentionally not supported (see #244, #299) 

889 TqdmDeprecationWarning( 

890 "Except func, normal arguments are intentionally" + 

891 " not supported by" + 

892 " `(DataFrame|Series|GroupBy).progress_apply`." + 

893 " Use keyword arguments instead.", 

894 fp_write=getattr(t.fp, 'write', sys.stderr.write)) 

895 

896 try: # pandas>=1.3.0 

897 from pandas.core.common import is_builtin_func 

898 except ImportError: 

899 is_builtin_func = df._is_builtin_func 

900 try: 

901 func = is_builtin_func(func) 

902 except TypeError: 

903 pass 

904 

905 # Define bar updating wrapper 

906 def wrapper(*args, **kwargs): 

907 # update tbar correctly 

908 # it seems `pandas apply` calls `func` twice 

909 # on the first column/row to decide whether it can 

910 # take a fast or slow code path; so stop when t.total==t.n 

911 t.update(n=1 if not t.total or t.n < t.total else 0) 

912 return func(*args, **kwargs) 

913 

914 # Apply the provided function (in **kwargs) 

915 # on the df using our wrapper (which provides bar updating) 

916 try: 

917 return getattr(df, df_function)(wrapper, **kwargs) 

918 finally: 

919 t.close() 

920 

921 return inner 

922 

923 # Monkeypatch pandas to provide easy methods 

924 # Enable custom tqdm progress in pandas! 

925 Series.progress_apply = inner_generator() 

926 SeriesGroupBy.progress_apply = inner_generator() 

927 Series.progress_map = inner_generator('map') 

928 SeriesGroupBy.progress_map = inner_generator('map') 

929 

930 DataFrame.progress_apply = inner_generator() 

931 DataFrameGroupBy.progress_apply = inner_generator() 

932 DataFrame.progress_applymap = inner_generator('applymap') 

933 DataFrame.progress_map = inner_generator('map') 

934 DataFrameGroupBy.progress_map = inner_generator('map') 

935 

936 if Panel is not None: 

937 Panel.progress_apply = inner_generator() 

938 if PanelGroupBy is not None: 

939 PanelGroupBy.progress_apply = inner_generator() 

940 

941 GroupBy.progress_apply = inner_generator() 

942 GroupBy.progress_aggregate = inner_generator('aggregate') 

943 GroupBy.progress_transform = inner_generator('transform') 

944 

945 if Rolling is not None and Expanding is not None: 

946 Rolling.progress_apply = inner_generator() 

947 Expanding.progress_apply = inner_generator() 

948 elif _Rolling_and_Expanding is not None: 

949 _Rolling_and_Expanding.progress_apply = inner_generator() 

950 

951 # override defaults via env vars 

952 @envwrap("TQDM_", is_method=True, types={'total': float, 'ncols': int, 'miniters': float, 

953 'position': int, 'nrows': int}) 

954 def __init__(self, iterable=None, desc=None, total=None, leave=True, file=None, 

955 ncols=None, mininterval=0.1, maxinterval=10.0, miniters=None, 

956 ascii=None, disable=False, unit='it', unit_scale=False, 

957 dynamic_ncols=False, smoothing=0.3, bar_format=None, initial=0, 

958 position=None, postfix=None, unit_divisor=1000, write_bytes=False, 

959 lock_args=None, nrows=None, colour=None, delay=0.0, gui=False, 

960 **kwargs): 

961 """see tqdm.tqdm for arguments""" 

962 if file is None: 

963 file = sys.stderr 

964 

965 if write_bytes: 

966 # Despite coercing unicode into bytes, py2 sys.std* streams 

967 # should have bytes written to them. 

968 file = SimpleTextIOWrapper( 

969 file, encoding=getattr(file, 'encoding', None) or 'utf-8') 

970 

971 file = DisableOnWriteError(file, tqdm_instance=self) 

972 

973 if disable is None and hasattr(file, "isatty") and not file.isatty(): 

974 disable = True 

975 

976 if total is None and iterable is not None: 

977 try: 

978 total = len(iterable) 

979 except (TypeError, AttributeError): 

980 total = None 

981 if total == float("inf"): 

982 # Infinite iterations, behave same as unknown 

983 total = None 

984 

985 if disable: 

986 self.iterable = iterable 

987 self.disable = disable 

988 with self._lock: 

989 self.pos = self._get_free_pos(self) 

990 self._instances.remove(self) 

991 self.n = initial 

992 self.total = total 

993 self.leave = leave 

994 return 

995 

996 if kwargs: 

997 self.disable = True 

998 with self._lock: 

999 self.pos = self._get_free_pos(self) 

1000 self._instances.remove(self) 

1001 raise ( 

1002 TqdmDeprecationWarning( 

1003 "`nested` is deprecated and automated.\n" 

1004 "Use `position` instead for manual control.\n", 

1005 fp_write=getattr(file, 'write', sys.stderr.write)) 

1006 if "nested" in kwargs else 

1007 TqdmKeyError("Unknown argument(s): " + str(kwargs))) 

1008 

1009 # Preprocess the arguments 

1010 if ( 

1011 (ncols is None or nrows is None) and (file in (sys.stderr, sys.stdout)) 

1012 ) or dynamic_ncols: # pragma: no cover 

1013 if dynamic_ncols: 

1014 dynamic_ncols = _screen_shape_wrapper() 

1015 if dynamic_ncols: 

1016 ncols, nrows = dynamic_ncols(file) 

1017 else: 

1018 _dynamic_ncols = _screen_shape_wrapper() 

1019 if _dynamic_ncols: 

1020 _ncols, _nrows = _dynamic_ncols(file) 

1021 if ncols is None: 

1022 ncols = _ncols 

1023 if nrows is None: 

1024 nrows = _nrows 

1025 

1026 if miniters is None: 

1027 miniters = 0 

1028 dynamic_miniters = True 

1029 else: 

1030 dynamic_miniters = False 

1031 

1032 if mininterval is None: 

1033 mininterval = 0 

1034 

1035 if maxinterval is None: 

1036 maxinterval = 0 

1037 

1038 if ascii is None: 

1039 ascii = not _supports_unicode(file) 

1040 

1041 if bar_format and ascii is not True and not _is_ascii(ascii): 

1042 # Convert bar format into unicode since terminal uses unicode 

1043 bar_format = str(bar_format) 

1044 

1045 if smoothing is None: 

1046 smoothing = 0 

1047 

1048 # Store the arguments 

1049 self.iterable = iterable 

1050 self.desc = desc or '' 

1051 self.total = total 

1052 self.leave = leave 

1053 self.fp = file 

1054 self.ncols = ncols 

1055 self.nrows = nrows 

1056 self.mininterval = mininterval 

1057 self.maxinterval = maxinterval 

1058 self.miniters = miniters 

1059 self.dynamic_miniters = dynamic_miniters 

1060 self.ascii = ascii 

1061 self.disable = disable 

1062 self.unit = unit 

1063 self.unit_scale = unit_scale 

1064 self.unit_divisor = unit_divisor 

1065 self.initial = initial 

1066 self.lock_args = lock_args 

1067 self.delay = delay 

1068 self.gui = gui 

1069 self.dynamic_ncols = dynamic_ncols 

1070 self.smoothing = smoothing 

1071 self._ema_dn = EMA(smoothing) 

1072 self._ema_dt = EMA(smoothing) 

1073 self._ema_miniters = EMA(smoothing) 

1074 self.bar_format = bar_format 

1075 self.postfix = None 

1076 self.colour = colour 

1077 self._time = time 

1078 if postfix: 

1079 try: 

1080 self.set_postfix(refresh=False, **postfix) 

1081 except TypeError: 

1082 self.postfix = postfix 

1083 

1084 # Init the iterations counters 

1085 self.last_print_n = initial 

1086 self.n = initial 

1087 

1088 # if nested, at initial sp() call we replace '\r' by '\n' to 

1089 # not overwrite the outer progress bar 

1090 with self._lock: 

1091 # mark fixed positions as negative 

1092 self.pos = self._get_free_pos(self) if position is None else -position 

1093 

1094 if not gui: 

1095 # Initialize the screen printer 

1096 self.sp = self.status_printer(self.fp) 

1097 if delay <= 0: 

1098 self.refresh(lock_args=self.lock_args) 

1099 

1100 # Init the time counter 

1101 self.last_print_t = self._time() 

1102 # NB: Avoid race conditions by setting start_t at the very end of init 

1103 self.start_t = self.last_print_t 

1104 

1105 def __bool__(self): 

1106 if self.total is not None: 

1107 return self.total > 0 

1108 if self.iterable is None: 

1109 raise TypeError('bool() undefined when iterable == total == None') 

1110 return bool(self.iterable) 

1111 

1112 def __len__(self): 

1113 return ( 

1114 self.total if self.iterable is None 

1115 else self.iterable.shape[0] if hasattr(self.iterable, "shape") 

1116 else len(self.iterable) if hasattr(self.iterable, "__len__") 

1117 else self.iterable.__length_hint__() if hasattr(self.iterable, "__length_hint__") 

1118 else getattr(self, "total", None)) 

1119 

1120 def __reversed__(self): 

1121 try: 

1122 orig = self.iterable 

1123 except AttributeError: 

1124 raise TypeError("'tqdm' object is not reversible") 

1125 else: 

1126 self.iterable = reversed(self.iterable) 

1127 return self.__iter__() 

1128 finally: 

1129 self.iterable = orig 

1130 

1131 def __contains__(self, item): 

1132 contains = getattr(self.iterable, '__contains__', None) 

1133 return contains(item) if contains is not None else item in self.__iter__() 

1134 

1135 def __enter__(self): 

1136 return self 

1137 

1138 def __exit__(self, exc_type, exc_value, traceback): 

1139 try: 

1140 self.close() 

1141 except AttributeError: 

1142 # maybe eager thread cleanup upon external error 

1143 if (exc_type, exc_value, traceback) == (None, None, None): 

1144 raise 

1145 warn("AttributeError ignored", TqdmWarning, stacklevel=2) 

1146 

1147 def __del__(self): 

1148 self.close() 

1149 

1150 def __str__(self): 

1151 return self.format_meter(**self.format_dict) 

1152 

1153 @property 

1154 def _comparable(self): 

1155 return abs(getattr(self, "pos", 1 << 31)) 

1156 

1157 def __hash__(self): 

1158 return id(self) 

1159 

1160 def __iter__(self): 

1161 """Backward-compatibility to use: for x in tqdm(iterable)""" 

1162 

1163 # Inlining instance variables as locals (speed optimisation) 

1164 iterable = self.iterable 

1165 

1166 # If the bar is disabled, then just walk the iterable 

1167 # (note: keep this check outside the loop for performance) 

1168 if self.disable: 

1169 for obj in iterable: 

1170 yield obj 

1171 return 

1172 

1173 mininterval = self.mininterval 

1174 last_print_t = self.last_print_t 

1175 last_print_n = self.last_print_n 

1176 min_start_t = self.start_t + self.delay 

1177 n = self.n 

1178 time = self._time 

1179 

1180 try: 

1181 for obj in iterable: 

1182 yield obj 

1183 # Update and possibly print the progressbar. 

1184 # Note: does not call self.update(1) for speed optimisation. 

1185 n += 1 

1186 

1187 if n - last_print_n >= self.miniters: 

1188 cur_t = time() 

1189 dt = cur_t - last_print_t 

1190 if dt >= mininterval and cur_t >= min_start_t: 

1191 self.update(n - last_print_n) 

1192 last_print_n = self.last_print_n 

1193 last_print_t = self.last_print_t 

1194 finally: 

1195 self.n = n 

1196 self.close() 

1197 

1198 def update(self, n=1): 

1199 """ 

1200 Manually update the progress bar, useful for streams 

1201 such as reading files. 

1202 E.g.: 

1203 >>> t = tqdm(total=filesize) # Initialise 

1204 >>> for current_buffer in stream: 

1205 ... ... 

1206 ... t.update(len(current_buffer)) 

1207 >>> t.close() 

1208 The last line is highly recommended, but possibly not necessary if 

1209 `t.update()` will be called in such a way that `filesize` will be 

1210 exactly reached and printed. 

1211 

1212 Parameters 

1213 ---------- 

1214 n : int or float, optional 

1215 Increment to add to the internal counter of iterations 

1216 [default: 1]. If using float, consider specifying `{n:.3f}` 

1217 or similar in `bar_format`, or specifying `unit_scale`. 

1218 

1219 Returns 

1220 ------- 

1221 out : bool or None 

1222 True if a `display()` was triggered. 

1223 """ 

1224 if self.disable: 

1225 return 

1226 

1227 if n < 0: 

1228 self.last_print_n += n # for auto-refresh logic to work 

1229 self.n += n 

1230 

1231 # check counter first to reduce calls to time() 

1232 if self.n - self.last_print_n >= self.miniters: 

1233 cur_t = self._time() 

1234 dt = cur_t - self.last_print_t 

1235 if dt >= self.mininterval and cur_t >= self.start_t + self.delay: 

1236 cur_t = self._time() 

1237 dn = self.n - self.last_print_n # >= n 

1238 if self.smoothing and dt and dn: 

1239 # EMA (not just overall average) 

1240 self._ema_dn(dn) 

1241 self._ema_dt(dt) 

1242 self.refresh(lock_args=self.lock_args) 

1243 if self.dynamic_miniters: 

1244 # If no `miniters` was specified, adjust automatically to the 

1245 # maximum iteration rate seen so far between two prints. 

1246 # e.g.: After running `tqdm.update(5)`, subsequent 

1247 # calls to `tqdm.update()` will only cause an update after 

1248 # at least 5 more iterations. 

1249 if self.maxinterval and dt >= self.maxinterval: 

1250 self.miniters = dn * (self.mininterval or self.maxinterval) / dt 

1251 elif self.smoothing: 

1252 # EMA miniters update 

1253 self.miniters = self._ema_miniters( 

1254 dn * (self.mininterval / dt if self.mininterval and dt 

1255 else 1)) 

1256 else: 

1257 # max iters between two prints 

1258 self.miniters = max(self.miniters, dn) 

1259 

1260 # Store old values for next call 

1261 self.last_print_n = self.n 

1262 self.last_print_t = cur_t 

1263 return True 

1264 

1265 def close(self): 

1266 """Cleanup and (if leave=False) close the progressbar.""" 

1267 if self.disable: 

1268 return 

1269 

1270 # Prevent multiple closures 

1271 self.disable = True 

1272 

1273 # decrement instance pos and remove from internal set 

1274 pos = abs(self.pos) 

1275 self._decr_instances(self) 

1276 

1277 if self.last_print_t < self.start_t + self.delay: 

1278 # haven't ever displayed; nothing to clear 

1279 return 

1280 

1281 # GUI mode 

1282 if getattr(self, 'sp', None) is None: 

1283 return 

1284 

1285 # annoyingly, _supports_unicode isn't good enough 

1286 def fp_write(s): 

1287 self.fp.write(str(s)) 

1288 

1289 try: 

1290 fp_write('') 

1291 except ValueError as e: 

1292 if 'closed' in str(e): 

1293 return 

1294 raise # pragma: no cover 

1295 

1296 leave = pos == 0 if self.leave is None else self.leave 

1297 

1298 with self._lock: 

1299 if leave: 

1300 # stats for overall rate (no weighted average) 

1301 self._ema_dt = lambda: None 

1302 self.display(pos=0) 

1303 fp_write('\n') 

1304 else: 

1305 # clear previous display 

1306 if self.display(msg='', pos=pos) and not pos: 

1307 fp_write('\r') 

1308 

1309 def clear(self, nolock=False): 

1310 """Clear current bar display.""" 

1311 if self.disable: 

1312 return 

1313 

1314 if not nolock: 

1315 self._lock.acquire() 

1316 pos = abs(self.pos) 

1317 if pos < (self.nrows or 20): 

1318 self.moveto(pos) 

1319 self.sp('') 

1320 self.fp.write('\r') # place cursor back at the beginning of line 

1321 self.moveto(-pos) 

1322 if not nolock: 

1323 self._lock.release() 

1324 

1325 def refresh(self, nolock=False, lock_args=None): 

1326 """ 

1327 Force refresh the display of this bar. 

1328 

1329 Parameters 

1330 ---------- 

1331 nolock : bool, optional 

1332 If `True`, does not lock. 

1333 If [default: `False`]: calls `acquire()` on internal lock. 

1334 lock_args : tuple, optional 

1335 Passed to internal lock's `acquire()`. 

1336 If specified, will only `display()` if `acquire()` returns `True`. 

1337 """ 

1338 if self.disable: 

1339 return 

1340 

1341 if not nolock: 

1342 if lock_args: 

1343 if not self._lock.acquire(*lock_args): 

1344 return False 

1345 else: 

1346 self._lock.acquire() 

1347 self.display() 

1348 if not nolock: 

1349 self._lock.release() 

1350 return True 

1351 

1352 def unpause(self): 

1353 """Restart tqdm timer from last print time.""" 

1354 if self.disable: 

1355 return 

1356 cur_t = self._time() 

1357 self.start_t += cur_t - self.last_print_t 

1358 self.last_print_t = cur_t 

1359 

1360 def reset(self, total=None): 

1361 """ 

1362 Resets to 0 iterations for repeated use. 

1363 

1364 Consider combining with `leave=True`. 

1365 

1366 Parameters 

1367 ---------- 

1368 total : int or float, optional. Total to use for the new bar. 

1369 """ 

1370 self.n = 0 

1371 if total is not None: 

1372 self.total = total 

1373 if self.disable: 

1374 return 

1375 self.last_print_n = 0 

1376 self.last_print_t = self.start_t = self._time() 

1377 self._ema_dn = EMA(self.smoothing) 

1378 self._ema_dt = EMA(self.smoothing) 

1379 self._ema_miniters = EMA(self.smoothing) 

1380 self.refresh() 

1381 

1382 def set_description(self, desc=None, refresh=True): 

1383 """ 

1384 Set/modify description of the progress bar. 

1385 

1386 Parameters 

1387 ---------- 

1388 desc : str, optional 

1389 refresh : bool, optional 

1390 Forces refresh [default: True]. 

1391 """ 

1392 self.desc = desc + ': ' if desc else '' 

1393 if refresh: 

1394 self.refresh() 

1395 

1396 def set_description_str(self, desc=None, refresh=True): 

1397 """Set/modify description without ': ' appended.""" 

1398 self.desc = desc or '' 

1399 if refresh: 

1400 self.refresh() 

1401 

1402 def set_postfix(self, ordered_dict=None, refresh=True, **kwargs): 

1403 """ 

1404 Set/modify postfix (additional stats) 

1405 with automatic formatting based on datatype. 

1406 

1407 Parameters 

1408 ---------- 

1409 ordered_dict : dict or OrderedDict, optional 

1410 refresh : bool, optional 

1411 Forces refresh [default: True]. 

1412 kwargs : dict, optional 

1413 """ 

1414 # Sort in alphabetical order to be more deterministic 

1415 postfix = OrderedDict([] if ordered_dict is None else ordered_dict) 

1416 for key in sorted(kwargs.keys()): 

1417 postfix[key] = kwargs[key] 

1418 # Preprocess stats according to datatype 

1419 for key in postfix.keys(): 

1420 # Number: limit the length of the string 

1421 if isinstance(postfix[key], Number): 

1422 postfix[key] = self.format_num(postfix[key]) 

1423 # Else for any other type, try to get the string conversion 

1424 elif not isinstance(postfix[key], str): 

1425 postfix[key] = str(postfix[key]) 

1426 # Else if it's a string, don't need to preprocess anything 

1427 # Stitch together to get the final postfix 

1428 self.postfix = ', '.join(key + '=' + postfix[key].strip() 

1429 for key in postfix.keys()) 

1430 if refresh: 

1431 self.refresh() 

1432 

1433 def set_postfix_str(self, s='', refresh=True): 

1434 """ 

1435 Postfix without dictionary expansion, similar to prefix handling. 

1436 """ 

1437 self.postfix = str(s) 

1438 if refresh: 

1439 self.refresh() 

1440 

1441 def moveto(self, n): 

1442 # TODO: private method 

1443 self.fp.write('\n' * n + _term_move_up() * -n) 

1444 getattr(self.fp, 'flush', lambda: None)() 

1445 

1446 @property 

1447 def format_dict(self): 

1448 """Public API for read-only member access.""" 

1449 if self.disable and not hasattr(self, 'unit'): 

1450 return defaultdict(lambda: None, { 

1451 'n': self.n, 'total': self.total, 'elapsed': 0, 'unit': 'it'}) 

1452 if self.dynamic_ncols: 

1453 self.ncols, self.nrows = self.dynamic_ncols(self.fp) 

1454 return { 

1455 'n': self.n, 'total': self.total, 

1456 'elapsed': self._time() - self.start_t if hasattr(self, 'start_t') else 0, 

1457 'ncols': self.ncols, 'nrows': self.nrows, 'prefix': self.desc, 

1458 'ascii': self.ascii, 'unit': self.unit, 'unit_scale': self.unit_scale, 

1459 'rate': self._ema_dn() / self._ema_dt() if self._ema_dt() else None, 

1460 'bar_format': self.bar_format, 'postfix': self.postfix, 

1461 'unit_divisor': self.unit_divisor, 'initial': self.initial, 

1462 'colour': self.colour} 

1463 

1464 def display(self, msg=None, pos=None): 

1465 """ 

1466 Use `self.sp` to display `msg` in the specified `pos`. 

1467 

1468 Consider overloading this function when inheriting to use e.g.: 

1469 `self.some_frontend(**self.format_dict)` instead of `self.sp`. 

1470 

1471 Parameters 

1472 ---------- 

1473 msg : str, optional. What to display (default: `repr(self)`). 

1474 pos : int, optional. Position to `moveto` 

1475 (default: `abs(self.pos)`). 

1476 """ 

1477 if pos is None: 

1478 pos = abs(self.pos) 

1479 

1480 nrows = self.nrows or 20 

1481 if pos >= nrows - 1: 

1482 if pos >= nrows: 

1483 return False 

1484 if msg or msg is None: # override at `nrows - 1` 

1485 msg = " ... (more hidden) ..." 

1486 

1487 if not hasattr(self, "sp"): 

1488 raise TqdmDeprecationWarning( 

1489 "Please use `tqdm.gui.tqdm(...)`" 

1490 " instead of `tqdm(..., gui=True)`\n", 

1491 fp_write=getattr(self.fp, 'write', sys.stderr.write)) 

1492 

1493 if pos: 

1494 self.moveto(pos) 

1495 self.sp(self.__str__() if msg is None else msg) 

1496 if pos: 

1497 self.moveto(-pos) 

1498 return True 

1499 

1500 @classmethod 

1501 @contextmanager 

1502 def wrapattr(cls, stream, method, total=None, bytes=True, **tqdm_kwargs): 

1503 """ 

1504 stream : file-like object. 

1505 method : str, "read" or "write". The result of `read()` and 

1506 the first argument of `write()` should have a `len()`. 

1507 

1508 >>> with tqdm.wrapattr(file_obj, "read", total=file_obj.size) as fobj: 

1509 ... while True: 

1510 ... chunk = fobj.read(chunk_size) 

1511 ... if not chunk: 

1512 ... break 

1513 """ 

1514 with cls(total=total, **tqdm_kwargs) as t: 

1515 if bytes: 

1516 t.unit = "B" 

1517 t.unit_scale = True 

1518 t.unit_divisor = 1024 

1519 yield CallbackIOWrapper(t.update, stream, method) 

1520 

1521 

1522def trange(*args, **kwargs): 

1523 """Shortcut for tqdm(range(*args), **kwargs).""" 

1524 return tqdm(range(*args), **kwargs)