Job#

class lumopt2.utils.runner.Job(task: str | Callable, label: str, inputs: List[Any] | None = None, dependencies: List[str] | None = None)#

Class representing a single job.

Parameters:
taskUnion[str, Callable]

Either a path to a .fsp or .py file, or a callable Python function.

labelstr

Unique identifier for the job. Other jobs reference this label in their dependencies list to express ordering constraints.

inputsOptional[List[Any]], optional

Input arguments for a Python function task. None (the default) indicates that the task should be invoked with no arguments and is treated as such by the runner; pass an empty list explicitly if you want to make the “no arguments” intent visible at the call site.

dependenciesOptional[List[str]], optional

Labels of jobs that must reach the ``’done’`` state before this job is allowed to start. None (the default) and an empty list both mean “no dependencies; this job is free to run as soon as the runner picks it up”.

Semantics across runner backends:

  • LocalRunner walks the dependency list recursively (run_dependencies) and runs each missing dependency synchronously before the dependent job; circular dependencies are detected up front (check_circular_dependencies).

  • Cluster runners (BashRunner / SLURM-style) translate the labels into the cluster’s native job-id chain (afterok:<id1>:<id2>:...) so the scheduler enforces the ordering instead of the runner.

Either way, dependencies are expressed by label (not by Job instance) so jobs can be added in any order before runjobs is called.

Notes

Mutable defaults (inputs=[], dependencies=[]) are deliberately avoided here – a list literal in the signature would be shared across every Job(...) instance and silently aliased between jobs that mutate their own list, leading to phantom “dependency on yourself” loops. __init__ materialises a fresh list in the body instead.