---
title: ExecStream
description: "A Python iterator, and async iterator, over an exec's output."
---

```python
@final
class ExecStream
```

A Python iterator, and async iterator, over an exec's output.

See the module docs for why this is a task and a bounded channel rather than a stored
future. `receiver` is behind a `Mutex` because `#[pyclass]` methods take `&self` when
the class is shared, and `recv` needs `&mut`; the lock is held only across one `recv`
and never across a Python callback, so it cannot deadlock against the GIL. tokio's, so a
coroutine can hold it across the `recv` it awaits.

## Constructor

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

## Special methods

### `__aiter__`

```python
def __aiter__() -> ExecStream
```

### `__anext__`

```python
def __anext__() -> Awaitable[OutputChunk | Gap | Exit]
```

The next event, awaited, or `StopAsyncIteration` when the stream ends: `async for`.

Cancelling the await leaves the event unread rather than lost: the channel keeps it
until the next `__anext__` or `__next__`.

### `__iter__`

```python
def __iter__() -> ExecStream
```

### `__next__`

```python
def __next__() -> OutputChunk | Gap | Exit
```

The next event, or `StopIteration` when the stream ends.

Blocks with the GIL released, so another Python thread can run while this one
waits on the daemon.

The end is raised rather than returned as `None`, which pyo3 would also turn into
`StopIteration`, because the stub is read off this return type: `None` would put
`| None` in an event loop's element type, where no `None` is ever yielded.

## 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.