from abc import ABC, abstractmethod from typing import Optional, Sequence from rope.base import exceptions, utils class BaseJobSet(ABC): name: str = "" job_name: str = "" @abstractmethod def started_job(self, name: str) -> None: pass @abstractmethod def finished_job(self) -> None: pass @abstractmethod def check_status(self) -> None: pass @utils.deprecated("Just use JobSet.job_name attribute/property instead") def get_active_job_name(self) -> str: pass @abstractmethod def get_percent_done(self) -> Optional[float]: pass @utils.deprecated("Just use JobSet.name attribute/property instead") def get_name(self) -> str: pass @abstractmethod def increment(self) -> None: """ Increment the number of tasks to complete. This is used if the number is not known ahead of time. """ pass class BaseTaskHandle(ABC): @abstractmethod def stop(self) -> None: pass @abstractmethod def current_jobset(self) -> Optional[BaseJobSet]: pass @abstractmethod def add_observer(self) -> None: pass @abstractmethod def is_stopped(self) -> bool: pass @abstractmethod def get_jobsets(self) -> Sequence[BaseJobSet]: pass def create_jobset( self, name: str = "JobSet", count: Optional[int] = None ) -> BaseJobSet: pass def _inform_observers(self) -> None: pass class TaskHandle(BaseTaskHandle): def __init__(self, name="Task", interrupts=True): """Construct a TaskHandle If `interrupts` is `False` the task won't be interrupted by calling `TaskHandle.stop()`. """ self.name = name self.interrupts = interrupts self.stopped = False self.job_sets = [] self.observers = [] def stop(self): """Interrupts the refactoring""" if self.interrupts: self.stopped = True self._inform_observers() def current_jobset(self): """Return the current `JobSet`""" if self.job_sets: return self.job_sets[-1] def add_observer(self, observer): """Register an observer for this task handle The observer is notified whenever the task is stopped or a job gets finished. """ self.observers.append(observer) def is_stopped(self): return self.stopped def get_jobsets(self): return self.job_sets def create_jobset(self, name="JobSet", count=None): result = JobSet(self, name=name, count=count) self.job_sets.append(result) self._inform_observers() return result def _inform_observers(self): for observer in list(self.observers): observer() class JobSet(BaseJobSet): def __init__(self, handle, name, count): self.handle = handle self.name = name self.count = count self.done = 0 self.job_name = None def started_job(self, name): self.check_status() self.job_name = name self.handle._inform_observers() def finished_job(self): self.check_status() self.done += 1 self.handle._inform_observers() self.job_name = None def check_status(self): if self.handle.is_stopped(): raise exceptions.InterruptedTaskError() @utils.deprecated("Just use JobSet.job_name attribute/property instead") def get_active_job_name(self): return self.job_name def get_percent_done(self): if self.count is not None and self.count > 0: percent = self.done * 100 // self.count return min(percent, 100) @utils.deprecated("Just use JobSet.name attribute/property instead") def get_name(self): return self.name def increment(self): self.count += 1 class NullTaskHandle(BaseTaskHandle): def is_stopped(self): return False def stop(self): pass def create_jobset(self, *args, **kwds): return NullJobSet() def get_jobsets(self): return [] def add_observer(self, observer): pass def current_jobset(self) -> None: """Return the current `JobSet`""" return None class NullJobSet(BaseJobSet): def started_job(self, name): pass def finished_job(self): pass def check_status(self): pass @utils.deprecated("Just use JobSet.job_name attribute/property instead") def get_active_job_name(self): pass def get_percent_done(self): pass @utils.deprecated("Just use JobSet.name attribute/property instead") def get_name(self): pass def increment(self): pass DEFAULT_TASK_HANDLE = NullTaskHandle() DEFAULT_JOB_SET = NullJobSet()