From 8dbc4d6aa318fbf26738c2d6e1ee0aebe8043d28 Mon Sep 17 00:00:00 2001 From: Sir Steven Gilroy Date: Mon, 2 Dec 2024 15:59:00 -0600 Subject: [PATCH] Remove `SkipNSteps` Exception (#22) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Néstor Pérez <25409753+prryplatypus@users.noreply.github.com> --- docs/docs/basics/manual-step-ordering.md | 4 +--- docs/docs/basics/workflow-path-hints.md | 2 +- ergate/__init__.py | 5 +---- ergate/exceptions.py | 8 -------- ergate/job.py | 14 +------------- ergate/job_runner.py | 24 ++++-------------------- ergate/paths.py | 7 ------- ergate/workflow.py | 5 +---- 8 files changed, 9 insertions(+), 60 deletions(-) diff --git a/docs/docs/basics/manual-step-ordering.md b/docs/docs/basics/manual-step-ordering.md index 489424b..184e74d 100644 --- a/docs/docs/basics/manual-step-ordering.md +++ b/docs/docs/basics/manual-step-ordering.md @@ -1,14 +1,12 @@ # Using workflow step names for manual ordering -Workflow steps may be manually ordered and redirected by use of `GoToEnd`, `GoToStep` and `SkipNSteps` exceptions. +Workflow steps may be manually ordered and redirected by use of `GoToEnd` and `GoToStep` exceptions. Workflow ordering can be preempted and redirected by raising the `GoToStep` exception, passing the workflow step function along with the optional return value. Workflows may also be advanced directly to completion by raising the `GoToEnd` exception. -Workflows may also be advanced by a set number of steps by raising the `SkipNSteps` exception. - ## Defining manual workflow order The following workflow contains five steps in total, which are executed in a specific order as directed by the diff --git a/docs/docs/basics/workflow-path-hints.md b/docs/docs/basics/workflow-path-hints.md index bcf3b9c..2175e45 100644 --- a/docs/docs/basics/workflow-path-hints.md +++ b/docs/docs/basics/workflow-path-hints.md @@ -10,7 +10,7 @@ completion percentage and total steps. This logic may be enabled by specifying the `paths=` kwarg for a given `@workflow.step()` decorator. * It is not necessary to specify `paths` for workflow steps which only return a value via `return`. -* It is suggested to define `paths` for steps which utilise the `SkipNSteps` or `GoToEnd` exceptions. +* It is suggested to define `paths` for steps which utilise the `GoToEnd` exceptions. * It is recommended to define `paths` for steps which utilise the `GoToStep` exception, or which have branching logic with multiple potential paths. `paths` may be freely defined alongside other kwargs in the `@workflow.step` decorator. diff --git a/ergate/__init__.py b/ergate/__init__.py index e9a9274..0f310fd 100644 --- a/ergate/__init__.py +++ b/ergate/__init__.py @@ -7,13 +7,12 @@ GoToStep, InvalidDefinitionError, ReverseGoToError, - SkipNSteps, UnknownStepError, ValidationError, ) from .job import Job from .job_status import JobStatus -from .paths import GoToEndPath, GoToStepPath, NextStepPath, SkipNStepsPath +from .paths import GoToEndPath, GoToStepPath, NextStepPath from .queue import QueueProtocol from .state_store import StateStoreProtocol from .workflow import Workflow, WorkflowStep @@ -35,8 +34,6 @@ "NextStepPath", "QueueProtocol", "ReverseGoToError", - "SkipNSteps", - "SkipNStepsPath", "StateStoreProtocol", "UnknownStepError", "ValidationError", diff --git a/ergate/exceptions.py b/ergate/exceptions.py index 84cdcef..245d582 100755 --- a/ergate/exceptions.py +++ b/ergate/exceptions.py @@ -43,11 +43,3 @@ class GoToStep(ErgateError): # noqa: N818 def __init__(self, step: WorkflowStep, *, retval: Any = None) -> None: self.retval = retval self.step = step - - -class SkipNSteps(ErgateError): # noqa: N818 - """Raised from a step to skip N steps.""" - - def __init__(self, n: int, retval: Any = None) -> None: - self.n = n - self.retval = retval diff --git a/ergate/job.py b/ergate/job.py index c70e8ae..8e43e63 100644 --- a/ergate/job.py +++ b/ergate/job.py @@ -41,19 +41,7 @@ def mark_step_n_completed( return_value: Any, total_steps: int, ) -> None: - self.mark_n_steps_completed( - n - self.current_step, - return_value, - total_steps, - ) - - def mark_n_steps_completed( - self, - n: int, - return_value: Any, - total_steps: int, - ) -> None: - self.current_step += n + self.current_step = n self.steps_completed = min(self.steps_completed + 1, total_steps) self.percent_completed = float((self.steps_completed / total_steps) * 100) self.status = ( diff --git a/ergate/job_runner.py b/ergate/job_runner.py index 01ea127..21ca485 100755 --- a/ergate/job_runner.py +++ b/ergate/job_runner.py @@ -1,11 +1,11 @@ from typing import Generic, TypeVar -from .exceptions import AbortJob, GoToEnd, GoToStep, ReverseGoToError, SkipNSteps +from .exceptions import AbortJob, GoToEnd, GoToStep, ReverseGoToError from .handler import ErrorHookHandler from .interrupt import DelayedKeyboardInterrupt from .job import Job from .log import LOG -from .paths import GoToStepPath, NextStepPath, SkipNStepsPath +from .paths import GoToStepPath, NextStepPath from .queue import QueueProtocol from .state_store import StateStoreProtocol from .workflow_registry import WorkflowRegistry @@ -83,22 +83,6 @@ def _run_job(self, job: JobType) -> None: job.mark_step_n_completed( exc.step.index, exc.retval, job.steps_completed + remaining_steps ) - except SkipNSteps as exc: - LOG.info("User requested to skip %d steps", exc.n) - - remaining_steps = max( - ( - len(path) - for path in paths - if isinstance(path[0][0], SkipNStepsPath) - and path[0][0].n == exc.n - ), - default=len(workflow) - job.current_step, - ) - - job.mark_n_steps_completed( - exc.n + 1, exc.retval, job.steps_completed + remaining_steps - ) except Exception as exc: # Since `except GoToStep` potentially raises an exception, the logic # for handling exceptions had to be moved to a higher scope. @@ -115,8 +99,8 @@ def _run_job(self, job: JobType) -> None: default=len(workflow) - job.current_step + 1, ) - job.mark_n_steps_completed( - 1, retval, job.steps_completed + remaining_steps + job.mark_step_n_completed( + job.current_step + 1, retval, job.steps_completed + remaining_steps ) except Exception as exc: LOG.exception("Job raised an exception") diff --git a/ergate/paths.py b/ergate/paths.py index 6a89ed1..3177653 100755 --- a/ergate/paths.py +++ b/ergate/paths.py @@ -15,10 +15,3 @@ def __init__(self, step_name: str) -> None: class NextStepPath(WorkflowPath): """WorkflowPath class for the default `return` from function.""" - - -class SkipNStepsPath(WorkflowPath): - """WorkflowPath class for the `SkipNSteps` exception.""" - - def __init__(self, n: int) -> None: - self.n = n diff --git a/ergate/workflow.py b/ergate/workflow.py index 94e2a11..02ee6fa 100755 --- a/ergate/workflow.py +++ b/ergate/workflow.py @@ -8,7 +8,7 @@ ) from .exceptions import ReverseGoToError, UnknownStepError -from .paths import GoToEndPath, GoToStepPath, NextStepPath, SkipNStepsPath, WorkflowPath +from .paths import GoToEndPath, GoToStepPath, NextStepPath, WorkflowPath from .workflow_step import WorkflowStep CallableSpec = ParamSpec("CallableSpec") @@ -103,9 +103,6 @@ def _find_next_step(self, index: int, path: WorkflowPath) -> int: if isinstance(path, GoToStepPath): return self.get_step_index_by_name(path.step_name) - if isinstance(path, SkipNStepsPath): - return index + 1 + path.n - return index + 1 def get_step_index_by_name(self, step_name: str) -> int: