---
title: ExecProcess
description: A running exec as two byte iterators, a wait(), and an idempotent kill().
---

```python
@final
class ExecProcess
```

A running exec as two byte iterators, a `wait()`, and an idempotent `kill()`.

Built by `Session.spawn`, never by a constructor: a process with no exec behind it is one
whose every method fails in a way that looks like a dead VM.

## Constructor

`ExecProcess` declares no `__new__` or `__init__`, so it is not constructed directly: an instance comes back from another call in this package.

## Properties

### `exec_id`

```python
exec_id: str
```

The exec id, which is the idempotency key: `Session.exec(exec_id)` reattaches to it.

### `gaps`

```python
gaps: list[OutputGap]
```

Every byte range the daemon couldn't replay, under `gap_policy="event"`. Empty under
the default policy, where a gap raises from both iterators instead.

### `stderr`

```python
stderr: ByteStream
```

The child's standard error. Order is kept within each side and isn't recoverable
between them; `ExecHandle.stream()` has the interleaving.

### `stdout`

```python
stdout: ByteStream
```

The child's standard output. The same iterator every time, since two over one side
would split its bytes between them.

## Methods

### `kill`

```python
def kill() -> bool
```

Signals the whole process group. Idempotent: `False` means nothing was signalled
because the group was already gone, which is the outcome a kill wanted, so a caller
can call this in a `finally` without guarding it.

### `kill_async`

```python
def kill_async() -> bool
```

The awaitable twin of `kill`.

### `wait`

```python
def wait(timeout: SupportsFloat | SupportsIndex | None = None) -> ExecResult
```

Polls the daemon's exec record until the command is done, or raises `TimeoutError`.

From the record, not from the iterators ending: a stream that stopped carrying bytes
is the same observation for a cut connection and a finished command. A timeout hasn't
touched the exec, so a caller can wait again. `timeout` defaults to `ExecHandle.wait`'s.

### `wait_async`

```python
def wait_async(timeout: SupportsFloat | SupportsIndex | None = None) -> ExecResult
```

The awaitable twin of `wait`. Cancelling it leaves the exec untouched.

## Special methods

### `__repr__`

```python
def __repr__() -> str
```

## Provenance

This page is generated from `bindings/microvms-py/microvms.pyi` by Griffe 2.3.0, run from `site/scripts/gen-reference.mjs` on every `pnpm run sync`, so an edit made here is overwritten by the next run.

To change the page, change the doc comment in the binding's Rust source, then regenerate the declarations with `mise run stubs`. `mise run stubs:check` fails when the committed file no longer matches the source.