Skip to content

ExecStream

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

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

def __aiter__() -> ExecStream
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__.

def __iter__() -> ExecStream
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.

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.