def test_track_thread() -> None: progress = Progress() task_id = progress.add_task("foo") track_thread = _TrackThread(progress, task_id, 0.1) assert track_thread.completed == 0 from time import sleep with track_thread: track_thread.completed = 1 sleep(0.2) assert progress.tasks[task_id].completed == 1 track_thread.completed += 1
def track( self, sequence: Union[Iterable[ProgressType], Sequence[ProgressType]], total: Optional[float] = None, task_id: Optional[TaskID] = None, description: str = "", update_period: float = 0.1, remove: bool = False, ) -> Iterable[ProgressType]: """Track progress by iterating over a sequence. Args: sequence (Sequence[ProgressType]): A sequence of values you want to iterate over and track progress. total: (float, optional): Total number of steps. Default is len(sequence). task_id: (TaskID): Task to track. Default is new task. description: (str, optional): Description of task, if new task is created. update_period (float, optional): Minimum time (in seconds) between calls to update(). Defaults to 0.1. Returns: Iterable[ProgressType]: An iterable of values taken from the provided sequence. """ if total is None: if isinstance(sequence, Sized): task_total = float(len(sequence)) else: raise ValueError( f"unable to get size of {sequence!r}, please specify 'total'" ) else: task_total = total if task_id is None: task_id = self.add_task(description, total=task_total) else: self.update(task_id, total=task_total) if self.live.auto_refresh: with _TrackThread(self, task_id, update_period) as track_thread: for value in sequence: yield value track_thread.completed += 1 else: advance = self.advance refresh = self.refresh for value in sequence: yield value advance(task_id, 1) refresh() if remove: self.remove_task(task_id)
def track( self, sequence: t.Union[ t.Sequence[r_progress.ProgressType], t.Iterable[r_progress.ProgressType] ], task_name: str, total: t.Optional[float] = None, description: str = None, update_period: float = 0.1, ) -> t.Generator[r_progress.ProgressType, None, None]: """ This can be better shortcut for add_task ... Specifically to be used directly on iterables ... Can add_task and also track it total: supply it when length of sequence cannot be guessed useful for infinite generators task_name: use # at end of task_task_name to support auto counter and hence reuse of task_name Refer: >>> r_progress.Progress.track >>> r_progress.track """ # ------------------------------------------------------------ 01 # estimate length if total is None: if isinstance(sequence, Sized): task_total = float(len(sequence)) else: raise ValueError( f"unable to get size of {sequence!r}, please specify 'total'" ) else: task_total = total # ------------------------------------------------------------ 02 # process task_name if task_name in self.tasks.keys(): raise e.validation.NotAllowed( msgs=[ f"There already exists a task named {task_name}" ] ) # if # in task name then add counter # note adding # will make task name reusable by adding counter _ = task_name.split("#") if len(_) == 2: task_name += str(len([k for k in self.tasks.keys() if k.startswith(_[0])])) # ------------------------------------------------------------ 03 # add task self.add_task(task_name=task_name, total=task_total, description=description) # ------------------------------------------------------------ 04 # yield and hence auto track # todo: explore --- self.rich_progress.live.auto_refresh task_id = self.tasks[task_name].id if self._progress.live.auto_refresh: # noinspection PyProtectedMember with r_progress._TrackThread( self._progress, task_id, update_period) as track_thread: for value in sequence: yield value track_thread.completed += 1 else: advance = self._progress.advance refresh = self._progress.refresh for value in sequence: yield value advance(task_id, 1) refresh()