Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/usethis/_pipeweld/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@


class Series(RootModel[list["Series | Parallel | DepGroup | str"]]):
"""An ordered sequence of pipeline components executed one after another."""

@override
def __hash__(self):
return hash((_HASH_SALT, tuple(self.root)))
Expand All @@ -30,6 +32,8 @@ def __len__(self):


class Parallel(RootModel[frozenset["Series | Parallel | DepGroup | str"]]):
"""An unordered set of pipeline components executed in parallel."""

@override
def __hash__(self):
return hash((_HASH_SALT, frozenset(self)))
Expand All @@ -51,6 +55,8 @@ def __len__(self):


class DepGroup(BaseModel):
"""A pipeline component tied to a named dependency configuration group."""

series: Series
config_group: str

Expand Down
14 changes: 14 additions & 0 deletions src/usethis/_pipeweld/func.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,30 @@


class Partition(BaseModel):
"""A three-way partition of a pipeline component relative to a new step's dependencies.

The three parts are: steps that must run before the new step (prerequisite),
steps independent of the new step (nondependent), and steps that must run after
the new step (postrequisite).
"""

prerequisite_component: str | Series | DepGroup | Parallel | None = None
nondependent_component: str | Series | DepGroup | Parallel | None = None
postrequisite_component: str | Series | DepGroup | Parallel | None = None
top_ranked_endpoint: str


class Adder(BaseModel):
"""Add a new step into an existing pipeline, respecting dependency ordering."""

pipeline: Series
step: str
prerequisites: set[str] = set()
postrequisites: set[str] = set()
compatible_config_groups: set[str] = set()

def add(self) -> WeldResult:
"""Add the step to the pipeline and return the modified pipeline with instructions."""
if len(self.pipeline) == 0:
# Empty pipeline
return WeldResult(
Expand Down Expand Up @@ -68,6 +78,10 @@ def add(self) -> WeldResult:
def partition_component(
self, component: str | Series | Parallel | DepGroup, *, predecessor: str | None
) -> tuple[Partition, list[Instruction]]:
"""Partition a component into prerequisite, nondependent, and postrequisite parts.

Returns the partition and any insertion instructions needed to perform the split.
"""
if isinstance(component, str):
if component in self.prerequisites:
return Partition(
Expand Down
6 changes: 6 additions & 0 deletions src/usethis/_pipeweld/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@


class BaseOperation(BaseModel):
"""Base class for pipeline insertion operations."""

after: str | None # None represents the source node
step: str


class InsertParallel(BaseOperation):
"""Insert a step in parallel with the step after the given predecessor."""

pass


class InsertSuccessor(BaseOperation):
"""Insert a step as the immediate successor of the given predecessor."""

pass


Expand Down
2 changes: 2 additions & 0 deletions src/usethis/_pipeweld/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@


class WeldResult(BaseModel):
"""The result of a pipeline welding operation."""

solution: Series
instructions: list[Instruction]
Loading