Detach
detach.DetachedRun
A launched detached run: its name, session-leader pid, and the log receiving its output.
Usage
detach.DetachedRun(
name,
pid,
log_path,
)Parameter Attributes
name: strpid: intlog_path: Path
Example
>>> run = await launch(["make", "corpus"], name="overnight")
>>> await wait(run.name)0
detach.launch()
Launch command as a detached, session-leader subprocess that outlives the caller.
Usage
detach.launch(command, *, name, on_spawn=None)The command runs under /bin/sh -c with stdout and stderr appended to logs_root/runs/<name>.log; once it exits the wrapper writes the real exit code to logs_root/runs/<name>.exit — a file separate from the shared log, so the detached child’s stdout cannot forge it — and wait() recovers the code from there. The configured env_prefix_cmd is prepended like a launchd agent.
Parameters
command: Sequence[str]-
The argv of the program to run.
name: str-
A unique name for the run; also names its log, pid, and exit files.
on_spawn: Callable[[DetachedRun], None] | None = None- Synchronous callback invoked with the run before post-spawn I/O.
Returns
DetachedRun- The launched run’s name, pid, and log path.
Raises
DetachError-
A live run already holds
name.
detach.wait()
Poll until the run’s process has exited and its .exit file appears, then return that code.
Usage
detach.wait(name, *, poll=5.0, timeout=None)Completion is proven by the process’s real exit — its pid is gone, per running() — together with the wrapper-written <name>.exit file, never by a line the detached child could print to the shared log. A child that forges an ATHOME-RUN-DONE line on stdout, or writes its own .exit file while still alive, cannot make this return early.
Parameters
name: str-
The run to wait on.
poll: float = 5.0-
Seconds to sleep between polls.
timeout: float | None = None-
Give up after this many seconds;
Nonewaits indefinitely.
Returns
int- The command’s exit code.
Raises
TimeoutError-
timeoutelapsed before the run finished.
detach.running()
Return the pid of the live run named name (pid file + kill -0), or None if none is alive.
Usage
detach.running(name)detach.DetachError
Raised when a detached run cannot start — most often a live run already owns the name.
Usage
detach.DetachError()