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

695 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:51 +0000

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 

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 

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

25__all__ = ['tqdm', 'trange', 

26 'TqdmTypeError', 'TqdmKeyError', 'TqdmWarning', 

27 'TqdmExperimentalWarning', 'TqdmDeprecationWarning', 

28 'TqdmMonitorWarning'] 

29 

30 

31class TqdmTypeError(TypeError): 

32 pass 

33 

34 

35class TqdmKeyError(KeyError): 

36 pass 

37 

38 

39class TqdmWarning(Warning): 

40 """base class for all tqdm warnings. 

41 

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

43 """ 

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

45 if fp_write is not None: 

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

47 else: 

48 super(TqdmWarning, self).__init__(msg, *a, **k) 

49 

50 

51class TqdmExperimentalWarning(TqdmWarning, FutureWarning): 

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

53 pass 

54 

55 

56class TqdmDeprecationWarning(TqdmWarning, DeprecationWarning): 

57 # not suppressed if raised 

58 pass 

59 

60 

61class TqdmMonitorWarning(TqdmWarning, RuntimeWarning): 

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

63 pass 

64 

65 

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

67 """threading RLock""" 

68 try: 

69 from threading import RLock 

70 return RLock(*args, **kwargs) 

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

72 pass 

73 

74 

75class TqdmDefaultWriteLock(object): 

76 """ 

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

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

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

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

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

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

83 """ 

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

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

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

87 th_lock = TRLock() 

88 

89 def __init__(self): 

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

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

92 cls = type(self) 

93 root_lock = cls.th_lock 

94 if root_lock is not None: 

95 root_lock.acquire() 

96 cls.create_mp_lock() 

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

98 if root_lock is not None: 

99 root_lock.release() 

100 

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

102 for lock in self.locks: 

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

104 

105 def release(self): 

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

107 lock.release() 

108 

109 def __enter__(self): 

110 self.acquire() 

111 

112 def __exit__(self, *exc): 

113 self.release() 

114 

115 @classmethod 

116 def create_mp_lock(cls): 

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

118 try: 

119 from multiprocessing import RLock 

120 cls.mp_lock = RLock() 

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

122 cls.mp_lock = None 

123 

124 @classmethod 

125 def create_th_lock(cls): 

126 assert hasattr(cls, 'th_lock') 

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

128 

129 

130class Bar(object): 

131 """ 

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

133 

134 - `width` 

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

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

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

138 - `type` 

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

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

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

142 """ 

143 ASCII = " 123456789#" 

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

145 BLANK = " " 

146 COLOUR_RESET = '\x1b[0m' 

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

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

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

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

151 

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

153 if not 0 <= frac <= 1: 

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

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

156 assert default_len > 0 

157 self.frac = frac 

158 self.default_len = default_len 

159 self.charset = charset 

160 self.colour = colour 

161 

162 @property 

163 def colour(self): 

164 return self._colour 

165 

166 @colour.setter 

167 def colour(self, value): 

168 if not value: 

169 self._colour = None 

170 return 

171 try: 

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

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

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

175 self._colour = self.COLOUR_RGB % tuple( 

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

177 else: 

178 raise KeyError 

179 except (KeyError, AttributeError): 

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

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

182 TqdmWarning, stacklevel=2) 

183 self._colour = None 

184 

185 def __format__(self, format_spec): 

186 if format_spec: 

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

188 try: 

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

190 except KeyError: 

191 charset = self.charset 

192 else: 

193 format_spec = format_spec[:-1] 

194 if format_spec: 

195 N_BARS = int(format_spec) 

196 if N_BARS < 0: 

197 N_BARS += self.default_len 

198 else: 

199 N_BARS = self.default_len 

200 else: 

201 charset = self.charset 

202 N_BARS = self.default_len 

203 

204 nsyms = len(charset) - 1 

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

206 

207 res = charset[-1] * bar_length 

208 if bar_length < N_BARS: # whitespace padding 

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

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

211 

212 

213class EMA(object): 

214 """ 

215 Exponential moving average: smoothing to give progressively lower 

216 weights to older values. 

217 

218 Parameters 

219 ---------- 

220 smoothing : float, optional 

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

222 Increase to give more weight to recent values. 

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

224 """ 

225 def __init__(self, smoothing=0.3): 

226 self.alpha = smoothing 

227 self.last = 0 

228 self.calls = 0 

229 

230 def __call__(self, x=None): 

231 """ 

232 Parameters 

233 ---------- 

234 x : float 

235 New value to include in EMA. 

236 """ 

237 beta = 1 - self.alpha 

238 if x is not None: 

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

240 self.calls += 1 

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

242 

243 

244class tqdm(Comparable): 

245 """ 

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

247 like the original iterable, but prints a dynamically updating 

248 progressbar every time a value is requested. 

249 """ 

250 

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

252 monitor = None 

253 _instances = WeakSet() 

254 

255 @staticmethod 

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

257 """ 

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

259 prefixes. 

260 

261 Parameters 

262 ---------- 

263 num : float 

264 Number ( >= 1) to format. 

265 suffix : str, optional 

266 Post-postfix [default: '']. 

267 divisor : float, optional 

268 Divisor between prefixes [default: 1000]. 

269 

270 Returns 

271 ------- 

272 out : str 

273 Number with Order of Magnitude SI unit postfix. 

274 """ 

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

276 if abs(num) < 999.5: 

277 if abs(num) < 99.95: 

278 if abs(num) < 9.995: 

279 return '{0:1.2f}'.format(num) + unit + suffix 

280 return '{0:2.1f}'.format(num) + unit + suffix 

281 return '{0:3.0f}'.format(num) + unit + suffix 

282 num /= divisor 

283 return '{0:3.1f}Y'.format(num) + suffix 

284 

285 @staticmethod 

286 def format_interval(t): 

287 """ 

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

289 

290 Parameters 

291 ---------- 

292 t : int 

293 Number of seconds. 

294 

295 Returns 

296 ------- 

297 out : str 

298 [H:]MM:SS 

299 """ 

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

301 h, m = divmod(mins, 60) 

302 if h: 

303 return '{0:d}:{1:02d}:{2:02d}'.format(h, m, s) 

304 else: 

305 return '{0:02d}:{1:02d}'.format(m, s) 

306 

307 @staticmethod 

308 def format_num(n): 

309 """ 

310 Intelligent scientific notation (.3g). 

311 

312 Parameters 

313 ---------- 

314 n : int or float or Numeric 

315 A Number. 

316 

317 Returns 

318 ------- 

319 out : str 

320 Formatted number. 

321 """ 

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

323 n = str(n) 

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

325 

326 @staticmethod 

327 def status_printer(file): 

328 """ 

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

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

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

332 """ 

333 fp = file 

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

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

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

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

338 

339 def fp_write(s): 

340 fp.write(str(s)) 

341 fp_flush() 

342 

343 last_len = [0] 

344 

345 def print_status(s): 

346 len_s = disp_len(s) 

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

348 last_len[0] = len_s 

349 

350 return print_status 

351 

352 @staticmethod 

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

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

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

356 """ 

357 Return a string-based progress bar given some parameters 

358 

359 Parameters 

360 ---------- 

361 n : int or float 

362 Number of finished iterations. 

363 total : int or float 

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

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

366 elapsed : float 

367 Number of seconds passed since start. 

368 ncols : int, optional 

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

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

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

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

373 prefix : str, optional 

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

375 Use as {desc} in bar_format string. 

376 ascii : bool, optional or str, optional 

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

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

379 " 123456789#". 

380 unit : str, optional 

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

382 unit_scale : bool or int or float, optional 

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

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

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

386 `total` and `n`. 

387 rate : float, optional 

388 Manual override for iteration rate. 

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

390 bar_format : str, optional 

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

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

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

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

395 '{rate_fmt}{postfix}]' 

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

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

398 rate, rate_fmt, rate_noinv, rate_noinv_fmt, 

399 rate_inv, rate_inv_fmt, postfix, unit_divisor, 

400 remaining, remaining_s, eta. 

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

402 if the latter is empty. 

403 postfix : *, optional 

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

405 (e.g. for additional stats). 

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

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

408 However other types are supported (#382). 

409 unit_divisor : float, optional 

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

411 initial : int or float, optional 

412 The initial counter value [default: 0]. 

413 colour : str, optional 

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

415 

416 Returns 

417 ------- 

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

419 """ 

420 

421 # sanity check: total 

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

423 total = None 

424 

425 # apply custom scale if necessary 

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

427 if total: 

428 total *= unit_scale 

429 n *= unit_scale 

430 if rate: 

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

432 unit_scale = False 

433 

434 elapsed_str = tqdm.format_interval(elapsed) 

435 

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

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

438 if rate is None and elapsed: 

439 rate = (n - initial) / elapsed 

440 inv_rate = 1 / rate if rate else None 

441 format_sizeof = tqdm.format_sizeof 

442 rate_noinv_fmt = ((format_sizeof(rate) if unit_scale else 

443 '{0:5.2f}'.format(rate)) if rate else '?') + unit + '/s' 

444 rate_inv_fmt = ( 

445 (format_sizeof(inv_rate) if unit_scale else '{0:5.2f}'.format(inv_rate)) 

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

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

448 

449 if unit_scale: 

450 n_fmt = format_sizeof(n, divisor=unit_divisor) 

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

452 else: 

453 n_fmt = str(n) 

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

455 

456 try: 

457 postfix = ', ' + postfix if postfix else '' 

458 except TypeError: 

459 pass 

460 

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

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

463 try: 

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

465 if rate and total else datetime.utcfromtimestamp(0)) 

466 except OverflowError: 

467 eta_dt = datetime.max 

468 

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

470 if prefix: 

471 # old prefix setup work around 

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

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

474 else: 

475 l_bar = '' 

476 

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

478 

479 # Custom bar formatting 

480 # Populate a dict with all available progress indicators 

481 format_dict = { 

482 # slight extension of self.format_dict 

483 'n': n, 'n_fmt': n_fmt, 'total': total, 'total_fmt': total_fmt, 

484 'elapsed': elapsed_str, 'elapsed_s': elapsed, 

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

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

487 'rate_fmt': rate_fmt, 'rate_noinv': rate, 

488 'rate_noinv_fmt': rate_noinv_fmt, 'rate_inv': inv_rate, 

489 'rate_inv_fmt': rate_inv_fmt, 

490 'postfix': postfix, 'unit_divisor': unit_divisor, 

491 'colour': colour, 

492 # plus more useful definitions 

493 'remaining': remaining_str, 'remaining_s': remaining, 

494 'l_bar': l_bar, 'r_bar': r_bar, 'eta': eta_dt, 

495 **extra_kwargs} 

496 

497 # total is known: we can predict some stats 

498 if total: 

499 # fractional and percentage progress 

500 frac = n / total 

501 percentage = frac * 100 

502 

503 l_bar += '{0:3.0f}%|'.format(percentage) 

504 

505 if ncols == 0: 

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

507 

508 format_dict.update(l_bar=l_bar) 

509 if bar_format: 

510 format_dict.update(percentage=percentage) 

511 

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

513 if not prefix: 

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

515 else: 

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

517 

518 full_bar = FormatReplace() 

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

520 if not full_bar.format_called: 

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

522 

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

524 full_bar = Bar(frac, 

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

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

527 colour=colour) 

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

529 bar_format = str(bar_format) 

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

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

532 

533 elif bar_format: 

534 # user-specified bar_format but no total 

535 l_bar += '|' 

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

537 full_bar = FormatReplace() 

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

539 if not full_bar.format_called: 

540 return nobar 

541 full_bar = Bar(0, 

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

543 charset=Bar.BLANK, colour=colour) 

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

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

546 else: 

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

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

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

550 

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

552 instance = object.__new__(cls) 

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

554 cls._instances.add(instance) 

555 # create monitoring thread 

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

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

558 try: 

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

560 except Exception as e: # pragma: nocover 

561 warn("tqdm:disabling monitor support" 

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

563 TqdmMonitorWarning, stacklevel=2) 

564 cls.monitor_interval = 0 

565 return instance 

566 

567 @classmethod 

568 def _get_free_pos(cls, instance=None): 

569 """Skips specified instance.""" 

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

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

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

573 

574 @classmethod 

575 def _decr_instances(cls, instance): 

576 """ 

577 Remove from list and reposition another unfixed bar 

578 to fill the new gap. 

579 

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

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

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

583 """ 

584 with cls._lock: 

585 try: 

586 cls._instances.remove(instance) 

587 except KeyError: 

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

589 # raise 

590 pass # py2: maybe magically removed already 

591 # else: 

592 if not instance.gui: 

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

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

595 instances = list(filter( 

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

597 cls._instances)) 

598 # set first found to current `pos` 

599 if instances: 

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

601 inst.clear(nolock=True) 

602 inst.pos = abs(instance.pos) 

603 

604 @classmethod 

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

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

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

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

609 # Write the message 

610 fp.write(s) 

611 fp.write(end) 

612 

613 @classmethod 

614 @contextmanager 

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

616 """ 

617 Disable tqdm within context and refresh tqdm when exits. 

618 Useful when writing to standard output stream 

619 """ 

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

621 

622 try: 

623 if not nolock: 

624 cls.get_lock().acquire() 

625 # Clear all bars 

626 inst_cleared = [] 

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

628 # Clear instance if in the target output file 

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

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

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

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

633 inst.clear(nolock=True) 

634 inst_cleared.append(inst) 

635 yield 

636 # Force refresh display of bars we cleared 

637 for inst in inst_cleared: 

638 inst.refresh(nolock=True) 

639 finally: 

640 if not nolock: 

641 cls._lock.release() 

642 

643 @classmethod 

644 def set_lock(cls, lock): 

645 """Set the global lock.""" 

646 cls._lock = lock 

647 

648 @classmethod 

649 def get_lock(cls): 

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

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

652 cls._lock = TqdmDefaultWriteLock() 

653 return cls._lock 

654 

655 @classmethod 

656 def pandas(cls, **tqdm_kwargs): 

657 """ 

658 Registers the current `tqdm` class with 

659 pandas.core. 

660 ( frame.DataFrame 

661 | series.Series 

662 | groupby.(generic.)DataFrameGroupBy 

663 | groupby.(generic.)SeriesGroupBy 

664 ).progress_apply 

665 

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

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

668 

669 Parameters 

670 ---------- 

671 tqdm_kwargs : arguments for the tqdm instance 

672 

673 Examples 

674 -------- 

675 >>> import pandas as pd 

676 >>> import numpy as np 

677 >>> from tqdm import tqdm 

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

679 >>> 

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

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

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

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

684 

685 References 

686 ---------- 

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

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

689 """ 

690 from warnings import catch_warnings, simplefilter 

691 

692 from pandas.core.frame import DataFrame 

693 from pandas.core.series import Series 

694 try: 

695 with catch_warnings(): 

696 simplefilter("ignore", category=FutureWarning) 

697 from pandas import Panel 

698 except ImportError: # pandas>=1.2.0 

699 Panel = None 

700 Rolling, Expanding = None, None 

701 try: # pandas>=1.0.0 

702 from pandas.core.window.rolling import _Rolling_and_Expanding 

703 except ImportError: 

704 try: # pandas>=0.18.0 

705 from pandas.core.window import _Rolling_and_Expanding 

706 except ImportError: # pandas>=1.2.0 

707 try: # pandas>=1.2.0 

708 from pandas.core.window.expanding import Expanding 

709 from pandas.core.window.rolling import Rolling 

710 _Rolling_and_Expanding = Rolling, Expanding 

711 except ImportError: # pragma: no cover 

712 _Rolling_and_Expanding = None 

713 try: # pandas>=0.25.0 

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

715 from pandas.core.groupby.generic import DataFrameGroupBy 

716 except ImportError: # pragma: no cover 

717 try: # pandas>=0.23.0 

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

719 except ImportError: 

720 from pandas.core.groupby import DataFrameGroupBy, SeriesGroupBy 

721 try: # pandas>=0.23.0 

722 from pandas.core.groupby.groupby import GroupBy 

723 except ImportError: # pragma: no cover 

724 from pandas.core.groupby import GroupBy 

725 

726 try: # pandas>=0.23.0 

727 from pandas.core.groupby.groupby import PanelGroupBy 

728 except ImportError: 

729 try: 

730 from pandas.core.groupby import PanelGroupBy 

731 except ImportError: # pandas>=0.25.0 

732 PanelGroupBy = None 

733 

734 tqdm_kwargs = tqdm_kwargs.copy() 

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

736 

737 def inner_generator(df_function='apply'): 

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

739 """ 

740 Parameters 

741 ---------- 

742 df : (DataFrame|Series)[GroupBy] 

743 Data (may be grouped). 

744 func : function 

745 To be applied on the (grouped) data. 

746 **kwargs : optional 

747 Transmitted to `df.apply()`. 

748 """ 

749 

750 # Precompute total iterations 

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

752 if total is None: # not grouped 

753 if df_function == 'applymap': 

754 total = df.size 

755 elif isinstance(df, Series): 

756 total = len(df) 

757 elif (_Rolling_and_Expanding is None or 

758 not isinstance(df, _Rolling_and_Expanding)): 

759 # DataFrame or Panel 

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

761 if axis == 'index': 

762 axis = 0 

763 elif axis == 'columns': 

764 axis = 1 

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

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

767 

768 # Init bar 

769 if deprecated_t[0] is not None: 

770 t = deprecated_t[0] 

771 deprecated_t[0] = None 

772 else: 

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

774 

775 if len(args) > 0: 

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

777 TqdmDeprecationWarning( 

778 "Except func, normal arguments are intentionally" + 

779 " not supported by" + 

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

781 " Use keyword arguments instead.", 

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

783 

784 try: # pandas>=1.3.0 

785 from pandas.core.common import is_builtin_func 

786 except ImportError: 

787 is_builtin_func = df._is_builtin_func 

788 try: 

789 func = is_builtin_func(func) 

790 except TypeError: 

791 pass 

792 

793 # Define bar updating wrapper 

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

795 # update tbar correctly 

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

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

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

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

800 return func(*args, **kwargs) 

801 

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

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

804 try: 

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

806 finally: 

807 t.close() 

808 

809 return inner 

810 

811 # Monkeypatch pandas to provide easy methods 

812 # Enable custom tqdm progress in pandas! 

813 Series.progress_apply = inner_generator() 

814 SeriesGroupBy.progress_apply = inner_generator() 

815 Series.progress_map = inner_generator('map') 

816 SeriesGroupBy.progress_map = inner_generator('map') 

817 

818 DataFrame.progress_apply = inner_generator() 

819 DataFrameGroupBy.progress_apply = inner_generator() 

820 DataFrame.progress_applymap = inner_generator('applymap') 

821 

822 if Panel is not None: 

823 Panel.progress_apply = inner_generator() 

824 if PanelGroupBy is not None: 

825 PanelGroupBy.progress_apply = inner_generator() 

826 

827 GroupBy.progress_apply = inner_generator() 

828 GroupBy.progress_aggregate = inner_generator('aggregate') 

829 GroupBy.progress_transform = inner_generator('transform') 

830 

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

832 Rolling.progress_apply = inner_generator() 

833 Expanding.progress_apply = inner_generator() 

834 elif _Rolling_and_Expanding is not None: 

835 _Rolling_and_Expanding.progress_apply = inner_generator() 

836 

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

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

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

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

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

842 lock_args=None, nrows=None, colour=None, delay=0, gui=False, 

843 **kwargs): 

844 """ 

845 Parameters 

846 ---------- 

847 iterable : iterable, optional 

848 Iterable to decorate with a progressbar. 

849 Leave blank to manually manage the updates. 

850 desc : str, optional 

851 Prefix for the progressbar. 

852 total : int or float, optional 

853 The number of expected iterations. If unspecified, 

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

855 resort, only basic progress statistics are displayed 

856 (no ETA, no progressbar). 

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

858 specify an initial arbitrary large positive number, 

859 e.g. 9e9. 

860 leave : bool, optional 

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

862 upon termination of iteration. 

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

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

865 Specifies where to output the progress messages 

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

867 methods. For encoding, see `write_bytes`. 

868 ncols : int, optional 

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

870 dynamically resizes the progressbar to stay within this bound. 

871 If unspecified, attempts to use environment width. The 

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

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

874 mininterval : float, optional 

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

876 maxinterval : float, optional 

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

878 Automatically adjusts `miniters` to correspond to `mininterval` 

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

880 or monitor thread is enabled. 

881 miniters : int or float, optional 

882 Minimum progress display update interval, in iterations. 

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

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

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

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

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

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

889 ascii : bool or str, optional 

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

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

892 disable : bool, optional 

893 Whether to disable the entire progressbar wrapper 

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

895 unit : str, optional 

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

897 [default: it]. 

898 unit_scale : bool or int or float, optional 

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

900 automatically and a metric prefix following the 

901 International System of Units standard will be added 

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

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

904 dynamic_ncols : bool, optional 

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

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

907 smoothing : float, optional 

908 Exponential moving average smoothing factor for speed estimates 

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

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

911 bar_format : str, optional 

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

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

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

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

916 '{rate_fmt}{postfix}]' 

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

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

919 rate, rate_fmt, rate_noinv, rate_noinv_fmt, 

920 rate_inv, rate_inv_fmt, postfix, unit_divisor, 

921 remaining, remaining_s, eta. 

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

923 if the latter is empty. 

924 initial : int or float, optional 

925 The initial counter value. Useful when restarting a progress 

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

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

928 position : int, optional 

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

930 Automatic if unspecified. 

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

932 postfix : dict or *, optional 

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

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

935 unit_divisor : float, optional 

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

937 write_bytes : bool, optional 

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

939 lock_args : tuple, optional 

940 Passed to `refresh` for intermediate output 

941 (initialisation, iterating, and updating). 

942 nrows : int, optional 

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

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

945 The fallback is 20. 

946 colour : str, optional 

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

948 delay : float, optional 

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

950 gui : bool, optional 

951 WARNING: internal parameter - do not use. 

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

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

954 

955 Returns 

956 ------- 

957 out : decorated iterator. 

958 """ 

959 if file is None: 

960 file = sys.stderr 

961 

962 if write_bytes: 

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

964 # should have bytes written to them. 

965 file = SimpleTextIOWrapper( 

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

967 

968 file = DisableOnWriteError(file, tqdm_instance=self) 

969 

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

971 disable = True 

972 

973 if total is None and iterable is not None: 

974 try: 

975 total = len(iterable) 

976 except (TypeError, AttributeError): 

977 total = None 

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

979 # Infinite iterations, behave same as unknown 

980 total = None 

981 

982 if disable: 

983 self.iterable = iterable 

984 self.disable = disable 

985 with self._lock: 

986 self.pos = self._get_free_pos(self) 

987 self._instances.remove(self) 

988 self.n = initial 

989 self.total = total 

990 self.leave = leave 

991 return 

992 

993 if kwargs: 

994 self.disable = True 

995 with self._lock: 

996 self.pos = self._get_free_pos(self) 

997 self._instances.remove(self) 

998 raise ( 

999 TqdmDeprecationWarning( 

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

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

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

1003 if "nested" in kwargs else 

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

1005 

1006 # Preprocess the arguments 

1007 if ( 

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

1009 ) or dynamic_ncols: # pragma: no cover 

1010 if dynamic_ncols: 

1011 dynamic_ncols = _screen_shape_wrapper() 

1012 if dynamic_ncols: 

1013 ncols, nrows = dynamic_ncols(file) 

1014 else: 

1015 _dynamic_ncols = _screen_shape_wrapper() 

1016 if _dynamic_ncols: 

1017 _ncols, _nrows = _dynamic_ncols(file) 

1018 if ncols is None: 

1019 ncols = _ncols 

1020 if nrows is None: 

1021 nrows = _nrows 

1022 

1023 if miniters is None: 

1024 miniters = 0 

1025 dynamic_miniters = True 

1026 else: 

1027 dynamic_miniters = False 

1028 

1029 if mininterval is None: 

1030 mininterval = 0 

1031 

1032 if maxinterval is None: 

1033 maxinterval = 0 

1034 

1035 if ascii is None: 

1036 ascii = not _supports_unicode(file) 

1037 

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

1039 # Convert bar format into unicode since terminal uses unicode 

1040 bar_format = str(bar_format) 

1041 

1042 if smoothing is None: 

1043 smoothing = 0 

1044 

1045 # Store the arguments 

1046 self.iterable = iterable 

1047 self.desc = desc or '' 

1048 self.total = total 

1049 self.leave = leave 

1050 self.fp = file 

1051 self.ncols = ncols 

1052 self.nrows = nrows 

1053 self.mininterval = mininterval 

1054 self.maxinterval = maxinterval 

1055 self.miniters = miniters 

1056 self.dynamic_miniters = dynamic_miniters 

1057 self.ascii = ascii 

1058 self.disable = disable 

1059 self.unit = unit 

1060 self.unit_scale = unit_scale 

1061 self.unit_divisor = unit_divisor 

1062 self.initial = initial 

1063 self.lock_args = lock_args 

1064 self.delay = delay 

1065 self.gui = gui 

1066 self.dynamic_ncols = dynamic_ncols 

1067 self.smoothing = smoothing 

1068 self._ema_dn = EMA(smoothing) 

1069 self._ema_dt = EMA(smoothing) 

1070 self._ema_miniters = EMA(smoothing) 

1071 self.bar_format = bar_format 

1072 self.postfix = None 

1073 self.colour = colour 

1074 self._time = time 

1075 if postfix: 

1076 try: 

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

1078 except TypeError: 

1079 self.postfix = postfix 

1080 

1081 # Init the iterations counters 

1082 self.last_print_n = initial 

1083 self.n = initial 

1084 

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

1086 # not overwrite the outer progress bar 

1087 with self._lock: 

1088 # mark fixed positions as negative 

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

1090 

1091 if not gui: 

1092 # Initialize the screen printer 

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

1094 if delay <= 0: 

1095 self.refresh(lock_args=self.lock_args) 

1096 

1097 # Init the time counter 

1098 self.last_print_t = self._time() 

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

1100 self.start_t = self.last_print_t 

1101 

1102 def __bool__(self): 

1103 if self.total is not None: 

1104 return self.total > 0 

1105 if self.iterable is None: 

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

1107 return bool(self.iterable) 

1108 

1109 def __len__(self): 

1110 return ( 

1111 self.total if self.iterable is None 

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

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

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

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

1116 

1117 def __reversed__(self): 

1118 try: 

1119 orig = self.iterable 

1120 except AttributeError: 

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

1122 else: 

1123 self.iterable = reversed(self.iterable) 

1124 return self.__iter__() 

1125 finally: 

1126 self.iterable = orig 

1127 

1128 def __contains__(self, item): 

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

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

1131 

1132 def __enter__(self): 

1133 return self 

1134 

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

1136 try: 

1137 self.close() 

1138 except AttributeError: 

1139 # maybe eager thread cleanup upon external error 

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

1141 raise 

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

1143 

1144 def __del__(self): 

1145 self.close() 

1146 

1147 def __str__(self): 

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

1149 

1150 @property 

1151 def _comparable(self): 

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

1153 

1154 def __hash__(self): 

1155 return id(self) 

1156 

1157 def __iter__(self): 

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

1159 

1160 # Inlining instance variables as locals (speed optimisation) 

1161 iterable = self.iterable 

1162 

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

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

1165 if self.disable: 

1166 for obj in iterable: 

1167 yield obj 

1168 return 

1169 

1170 mininterval = self.mininterval 

1171 last_print_t = self.last_print_t 

1172 last_print_n = self.last_print_n 

1173 min_start_t = self.start_t + self.delay 

1174 n = self.n 

1175 time = self._time 

1176 

1177 try: 

1178 for obj in iterable: 

1179 yield obj 

1180 # Update and possibly print the progressbar. 

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

1182 n += 1 

1183 

1184 if n - last_print_n >= self.miniters: 

1185 cur_t = time() 

1186 dt = cur_t - last_print_t 

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

1188 self.update(n - last_print_n) 

1189 last_print_n = self.last_print_n 

1190 last_print_t = self.last_print_t 

1191 finally: 

1192 self.n = n 

1193 self.close() 

1194 

1195 def update(self, n=1): 

1196 """ 

1197 Manually update the progress bar, useful for streams 

1198 such as reading files. 

1199 E.g.: 

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

1201 >>> for current_buffer in stream: 

1202 ... ... 

1203 ... t.update(len(current_buffer)) 

1204 >>> t.close() 

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

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

1207 exactly reached and printed. 

1208 

1209 Parameters 

1210 ---------- 

1211 n : int or float, optional 

1212 Increment to add to the internal counter of iterations 

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

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

1215 

1216 Returns 

1217 ------- 

1218 out : bool or None 

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

1220 """ 

1221 if self.disable: 

1222 return 

1223 

1224 if n < 0: 

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

1226 self.n += n 

1227 

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

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

1230 cur_t = self._time() 

1231 dt = cur_t - self.last_print_t 

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

1233 cur_t = self._time() 

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

1235 if self.smoothing and dt and dn: 

1236 # EMA (not just overall average) 

1237 self._ema_dn(dn) 

1238 self._ema_dt(dt) 

1239 self.refresh(lock_args=self.lock_args) 

1240 if self.dynamic_miniters: 

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

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

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

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

1245 # at least 5 more iterations. 

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

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

1248 elif self.smoothing: 

1249 # EMA miniters update 

1250 self.miniters = self._ema_miniters( 

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

1252 else 1)) 

1253 else: 

1254 # max iters between two prints 

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

1256 

1257 # Store old values for next call 

1258 self.last_print_n = self.n 

1259 self.last_print_t = cur_t 

1260 return True 

1261 

1262 def close(self): 

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

1264 if self.disable: 

1265 return 

1266 

1267 # Prevent multiple closures 

1268 self.disable = True 

1269 

1270 # decrement instance pos and remove from internal set 

1271 pos = abs(self.pos) 

1272 self._decr_instances(self) 

1273 

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

1275 # haven't ever displayed; nothing to clear 

1276 return 

1277 

1278 # GUI mode 

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

1280 return 

1281 

1282 # annoyingly, _supports_unicode isn't good enough 

1283 def fp_write(s): 

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

1285 

1286 try: 

1287 fp_write('') 

1288 except ValueError as e: 

1289 if 'closed' in str(e): 

1290 return 

1291 raise # pragma: no cover 

1292 

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

1294 

1295 with self._lock: 

1296 if leave: 

1297 # stats for overall rate (no weighted average) 

1298 self._ema_dt = lambda: None 

1299 self.display(pos=0) 

1300 fp_write('\n') 

1301 else: 

1302 # clear previous display 

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

1304 fp_write('\r') 

1305 

1306 def clear(self, nolock=False): 

1307 """Clear current bar display.""" 

1308 if self.disable: 

1309 return 

1310 

1311 if not nolock: 

1312 self._lock.acquire() 

1313 pos = abs(self.pos) 

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

1315 self.moveto(pos) 

1316 self.sp('') 

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

1318 self.moveto(-pos) 

1319 if not nolock: 

1320 self._lock.release() 

1321 

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

1323 """ 

1324 Force refresh the display of this bar. 

1325 

1326 Parameters 

1327 ---------- 

1328 nolock : bool, optional 

1329 If `True`, does not lock. 

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

1331 lock_args : tuple, optional 

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

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

1334 """ 

1335 if self.disable: 

1336 return 

1337 

1338 if not nolock: 

1339 if lock_args: 

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

1341 return False 

1342 else: 

1343 self._lock.acquire() 

1344 self.display() 

1345 if not nolock: 

1346 self._lock.release() 

1347 return True 

1348 

1349 def unpause(self): 

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

1351 if self.disable: 

1352 return 

1353 cur_t = self._time() 

1354 self.start_t += cur_t - self.last_print_t 

1355 self.last_print_t = cur_t 

1356 

1357 def reset(self, total=None): 

1358 """ 

1359 Resets to 0 iterations for repeated use. 

1360 

1361 Consider combining with `leave=True`. 

1362 

1363 Parameters 

1364 ---------- 

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

1366 """ 

1367 self.n = 0 

1368 if total is not None: 

1369 self.total = total 

1370 if self.disable: 

1371 return 

1372 self.last_print_n = 0 

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

1374 self._ema_dn = EMA(self.smoothing) 

1375 self._ema_dt = EMA(self.smoothing) 

1376 self._ema_miniters = EMA(self.smoothing) 

1377 self.refresh() 

1378 

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

1380 """ 

1381 Set/modify description of the progress bar. 

1382 

1383 Parameters 

1384 ---------- 

1385 desc : str, optional 

1386 refresh : bool, optional 

1387 Forces refresh [default: True]. 

1388 """ 

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

1390 if refresh: 

1391 self.refresh() 

1392 

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

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

1395 self.desc = desc or '' 

1396 if refresh: 

1397 self.refresh() 

1398 

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

1400 """ 

1401 Set/modify postfix (additional stats) 

1402 with automatic formatting based on datatype. 

1403 

1404 Parameters 

1405 ---------- 

1406 ordered_dict : dict or OrderedDict, optional 

1407 refresh : bool, optional 

1408 Forces refresh [default: True]. 

1409 kwargs : dict, optional 

1410 """ 

1411 # Sort in alphabetical order to be more deterministic 

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

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

1414 postfix[key] = kwargs[key] 

1415 # Preprocess stats according to datatype 

1416 for key in postfix.keys(): 

1417 # Number: limit the length of the string 

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

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

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

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

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

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

1424 # Stitch together to get the final postfix 

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

1426 for key in postfix.keys()) 

1427 if refresh: 

1428 self.refresh() 

1429 

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

1431 """ 

1432 Postfix without dictionary expansion, similar to prefix handling. 

1433 """ 

1434 self.postfix = str(s) 

1435 if refresh: 

1436 self.refresh() 

1437 

1438 def moveto(self, n): 

1439 # TODO: private method 

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

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

1442 

1443 @property 

1444 def format_dict(self): 

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

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

1447 return defaultdict(lambda: None, { 

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

1449 if self.dynamic_ncols: 

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

1451 return { 

1452 'n': self.n, 'total': self.total, 

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

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

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

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

1457 'bar_format': self.bar_format, 'postfix': self.postfix, 

1458 'unit_divisor': self.unit_divisor, 'initial': self.initial, 

1459 'colour': self.colour} 

1460 

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

1462 """ 

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

1464 

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

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

1467 

1468 Parameters 

1469 ---------- 

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

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

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

1473 """ 

1474 if pos is None: 

1475 pos = abs(self.pos) 

1476 

1477 nrows = self.nrows or 20 

1478 if pos >= nrows - 1: 

1479 if pos >= nrows: 

1480 return False 

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

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

1483 

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

1485 raise TqdmDeprecationWarning( 

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

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

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

1489 

1490 if pos: 

1491 self.moveto(pos) 

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

1493 if pos: 

1494 self.moveto(-pos) 

1495 return True 

1496 

1497 @classmethod 

1498 @contextmanager 

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

1500 """ 

1501 stream : file-like object. 

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

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

1504 

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

1506 ... while True: 

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

1508 ... if not chunk: 

1509 ... break 

1510 """ 

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

1512 if bytes: 

1513 t.unit = "B" 

1514 t.unit_scale = True 

1515 t.unit_divisor = 1024 

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

1517 

1518 

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

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

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