Post-Local sync at 2025-06-23T22:46:07Z
This commit is contained in:
parent
9d33b42020
commit
9f97801b0d
1387 changed files with 250216 additions and 117 deletions
95
.venv/lib/python3.12/site-packages/tqdm/_monitor.py
Normal file
95
.venv/lib/python3.12/site-packages/tqdm/_monitor.py
Normal file
|
@ -0,0 +1,95 @@
|
|||
import atexit
|
||||
from threading import Event, Thread, current_thread
|
||||
from time import time
|
||||
from warnings import warn
|
||||
|
||||
__all__ = ["TMonitor", "TqdmSynchronisationWarning"]
|
||||
|
||||
|
||||
class TqdmSynchronisationWarning(RuntimeWarning):
|
||||
"""tqdm multi-thread/-process errors which may cause incorrect nesting
|
||||
but otherwise no adverse effects"""
|
||||
pass
|
||||
|
||||
|
||||
class TMonitor(Thread):
|
||||
"""
|
||||
Monitoring thread for tqdm bars.
|
||||
Monitors if tqdm bars are taking too much time to display
|
||||
and readjusts miniters automatically if necessary.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
tqdm_cls : class
|
||||
tqdm class to use (can be core tqdm or a submodule).
|
||||
sleep_interval : float
|
||||
Time to sleep between monitoring checks.
|
||||
"""
|
||||
_test = {} # internal vars for unit testing
|
||||
|
||||
def __init__(self, tqdm_cls, sleep_interval):
|
||||
Thread.__init__(self)
|
||||
self.daemon = True # kill thread when main killed (KeyboardInterrupt)
|
||||
self.woken = 0 # last time woken up, to sync with monitor
|
||||
self.tqdm_cls = tqdm_cls
|
||||
self.sleep_interval = sleep_interval
|
||||
self._time = self._test.get("time", time)
|
||||
self.was_killed = self._test.get("Event", Event)()
|
||||
atexit.register(self.exit)
|
||||
self.start()
|
||||
|
||||
def exit(self):
|
||||
self.was_killed.set()
|
||||
if self is not current_thread():
|
||||
self.join()
|
||||
return self.report()
|
||||
|
||||
def get_instances(self):
|
||||
# returns a copy of started `tqdm_cls` instances
|
||||
return [i for i in self.tqdm_cls._instances.copy()
|
||||
# Avoid race by checking that the instance started
|
||||
if hasattr(i, 'start_t')]
|
||||
|
||||
def run(self):
|
||||
cur_t = self._time()
|
||||
while True:
|
||||
# After processing and before sleeping, notify that we woke
|
||||
# Need to be done just before sleeping
|
||||
self.woken = cur_t
|
||||
# Sleep some time...
|
||||
self.was_killed.wait(self.sleep_interval)
|
||||
# Quit if killed
|
||||
if self.was_killed.is_set():
|
||||
return
|
||||
# Then monitor!
|
||||
# Acquire lock (to access _instances)
|
||||
with self.tqdm_cls.get_lock():
|
||||
cur_t = self._time()
|
||||
# Check tqdm instances are waiting too long to print
|
||||
instances = self.get_instances()
|
||||
for instance in instances:
|
||||
# Check event in loop to reduce blocking time on exit
|
||||
if self.was_killed.is_set():
|
||||
return
|
||||
# Only if mininterval > 1 (else iterations are just slow)
|
||||
# and last refresh exceeded maxinterval
|
||||
if (
|
||||
instance.miniters > 1
|
||||
and (cur_t - instance.last_print_t) >= instance.maxinterval
|
||||
):
|
||||
# force bypassing miniters on next iteration
|
||||
# (dynamic_miniters adjusts mininterval automatically)
|
||||
instance.miniters = 1
|
||||
# Refresh now! (works only for manual tqdm)
|
||||
instance.refresh(nolock=True)
|
||||
# Remove accidental long-lived strong reference
|
||||
del instance
|
||||
if instances != self.get_instances(): # pragma: nocover
|
||||
warn("Set changed size during iteration" +
|
||||
" (see https://github.com/tqdm/tqdm/issues/481)",
|
||||
TqdmSynchronisationWarning, stacklevel=2)
|
||||
# Remove accidental long-lived strong references
|
||||
del instances
|
||||
|
||||
def report(self):
|
||||
return not self.was_killed.is_set()
|
Loading…
Add table
Add a link
Reference in a new issue