monty-proto
The wire protocol between pool parents and monty workers: the protobuf-generated messages, 4-byte length-prefixed framing, and validated conversions between wire frames and monty-types values.
pub const PROTOCOL_VERSION: u32 = 5;
Version of the wire schema this build speaks, sent in
pb::Configure::protocol_version and range-checked by the child.
Bump on any change a peer at the previous version could mis-read: removing or repurposing a field, changing a field’s meaning, or adding one the child requires. Purely additive changes an older peer can ignore do not need a bump.
pub const MIN_SUPPORTED_PROTOCOL_VERSION: u32 = 5;
Oldest PROTOCOL_VERSION this build still serves.
Version 4 and below are not served. Version 3 carried values as recursive
MontyObject trees, where this build carries one flat Arena per message.
Version 4 both lacked max_feed_duration/max_turn_duration and had the
per-session max_duration this build dropped: a version 4 parent would
send a budget nothing enforces, and a version 4 child would accept the new
budgets and ignore them. Neither side can be told apart from a working one,
so both are refused.
pub const DEFAULT_PRINT_FLUSH_INTERVAL: std::time::Duration = _;
How long the child holds buffered print() output before emitting it as a
Print event, when pb::Configure::print_flush_interval_ms says nothing.
Short enough to read as live output, long enough that a printing loop emits
events at a rate set by elapsed time rather than by how often the program
called print().
pub fn check_protocol_version(version: u32) -> Result<(), String>;
Checks a peer’s declared pb::Configure::protocol_version against the
range this build serves.
pub struct BudgetVec<T>(/* private */);
A protocol vector whose decoding growth is charged before allocation. Conversion to and from a standard vector transfers ownership without copying. Host construction and cloning do not require an active decode budget. In-place growth must propagate a decode error:
let mut values = monty_proto::BudgetVec::<u8>::new();
values.push(1);
pub const fn new() -> Self
Creates an empty buffer without allocating or requiring a decode scope.
pub fn into_inner(self) -> Vec<T>
Transfers decoded storage to a domain value without reallocating.
pub fn as_slice(&self) -> &[T]
Borrows the initialized elements without exposing vector growth.
pub fn capacity(&self) -> usize
Returns the backing allocation’s element capacity.
pub fn try_push(&mut self, value: T) -> Result<(), DecodeError>
Appends a decoded element, charging any required growth first.
pub fn clear(&mut self)
Removes elements while retaining their already-paid backing allocation.
pub fn truncate(&mut self, len: usize)
Discards trailing elements without changing the allocation charge.
Implements: AsRef<[T]>, Clone, Debug, Default, Deref, DerefMut, Eq, From<BudgetVec<T>>, From<Vec<T>>, FromIterator<T>, Hash, IntoIterator, PartialEq, PartialEq<&[T]>, PartialEq<Vec<T>>, StructuralPartialEq.
pub enum ProtoConvertError {
/// A required message field or oneof was absent.
MissingField(&'static str),
/// An exception type name that monty does not know.
UnknownExcType(String),
/// A type name that monty's `MontyType::from_type_name` does not know.
UnknownType(String),
/// A builtin function name that monty does not know.
UnknownBuiltinFunction(String),
/// A file handle mode string that is not a supported `open()` mode.
InvalidFileMode(String),
/// A `time.time` caller name that no `TimeCaller` spells.
InvalidTimeCaller(String),
/// A field value was out of range or otherwise malformed.
InvalidValue { field: &'static str, reason: String },
}
Why a wire value could not be converted into its monty equivalent.
Returned by all TryFrom<pb::...> impls in this crate. The variants are
deliberately specific so a parent can log exactly which field a misbehaving
child produced.
Implements: Debug, Display, Error.
pub fn ext_result_from_proto(
result: pb::ExtFunctionResult,
values: Option<WireArena>,
) -> Result<monty_types::ExtFunctionResult, ProtoConvertError>;
Validates a decoded call result against the arena its message carried.
pub fn ext_result_to_proto(
result: monty_types::ExtFunctionResult,
) -> (pb::ExtFunctionResult, Option<WireArena>);
Splits a call result into its wire kind and the arena a Return value
indexes (None for the other arms).
pub fn future_results_from_proto(
results: impl IntoIterator<Item = pb::FutureResult>,
values: Option<WireArena>,
) -> Result<Vec<(u32, monty_types::ExtFunctionResult)>, ProtoConvertError>;
Converts wire future results into (call_id, result) pairs for
ResolveFutures::resume; each returned value gets its own copy of the
nodes it reaches.
pub fn future_results_to_proto(
results: Vec<(u32, monty_types::ExtFunctionResult)>,
) -> pb::ResumeFutures;
Merges every returned value into one arena and points each ReturnValue
into it.
pub fn named_values_from_proto(
inputs: impl IntoIterator<Item = pb::NamedRef>,
values: Option<WireArena>,
) -> Result<monty_types::NamedValues, ProtoConvertError>;
Validates decoded named inputs against their arena.
pub fn named_values_to_proto(
inputs: monty_types::NamedValues,
) -> (BudgetVec<pb::NamedRef>, WireArena);
Splits named inputs into NamedRefs and the arena they index.
pub fn os_call_from_proto(
call: pb::OsCall,
) -> Result<(u32, monty_types::OsFunctionCall), ProtoConvertError>;
Validates a decoded OS call envelope into its call id and typed call.
pub fn os_call_to_proto(
call_id: u32,
call: monty_types::OsFunctionCall,
allow_eager_await: bool,
) -> pb::OsCall;
Builds the OsCall envelope: call id, typed arm, the eager-await hint and,
for Getenv, the arena its default indexes.
pub fn resume_call_from_proto(
call: pb::ResumeCall,
) -> Result<monty_types::ExtFunctionResult, ProtoConvertError>;
The result of a ResumeCall reply, read with its arena by
ext_result_from_proto.
pub const DEFAULT_MAX_DECODE_BYTES: usize = 1_073_741_824usize;
Per-frame ceiling on cumulative decoded allocation requests (1 GiB). Generated protocol messages and hand-written values budget vectors, buffers and boxes before allocating, including full replacement buffers on growth. Freed payloads are not refunded. Excludes the wire buffer, bounded decode stack/error overhead and allocator metadata; multiplies per concurrent decode.
pub enum FrameError {
/// Underlying stream I/O failure (includes broken pipes — peer death).
Io(io::Error),
/// Frame contents were not a valid protobuf message.
Decode(prost::DecodeError),
/// Length prefix exceeded the reader's maximum frame length.
FrameTooLarge { len: u32, max: u32 },
/// The stream ended mid-frame: the peer died while writing.
Truncated,
}
Framing or decoding failure while reading or writing protocol messages.
Implements: Debug, Display, Error, From<Error>.
pub struct FrameReader<R: Read> { /* private fields */ }
Reads length-prefixed protobuf frames from a byte stream.
pub fn new(inner: R) -> Self
Wraps a byte stream with the default MAX_FRAME_LEN.
pub fn with_max_frame_len(inner: R, max_frame_len: u32) -> Self
Wraps a byte stream with a custom maximum frame length.
pub fn read<M: Message + Default>(&mut self) -> Result<Option<M>, FrameError>
Reads one frame and decodes it as M.
Returns Ok(None) on a clean EOF at a frame boundary (the peer closed
the stream between messages). EOF inside a frame is
FrameError::Truncated — the peer died mid-write.
Implements: Debug.
pub const MAX_FRAME_LEN: u32 = 268_435_456u32;
Default maximum frame length (256 MiB).
Far above any sane payload, but small enough that a corrupted length prefix cannot trigger a multi-gigabyte allocation in the receiver.
pub fn decode_frame<M: Message + Default>(bytes: &[u8]) -> Result<M, FrameError>;
Decodes one already-deframed message from bytes.
The message-oriented counterpart to one FrameReader::read: a transport
whose boundary is the frame (a WebSocket) hands the payload straight here.
Rejects payloads over MAX_FRAME_LEN and scopes the decode allocation
budget, restoring any enclosing budget on return or unwind. The budget
applies to this crate’s protocol types, not arbitrary third-party messages.
pub fn encode_framed_into(msg: &impl Message, buf: &mut Vec<u8>) -> Result<(), FrameError>;
Encodes msg as one length-prefixed frame — prefix and body in a single
buffer — into buf (cleared first), enforcing MAX_FRAME_LEN before
encoding.
Byte-stream transports that own their write half directly (the pool’s
subprocess workers) send this with one write_all, halving the write
syscalls of a prefix-then-body pair; taking the buffer lets callers reuse
one allocation across frames.
pub fn encode_to_capped_vec(msg: &impl Message) -> Result<Vec<u8>, FrameError>;
Encodes msg to a Vec<u8>, enforcing MAX_FRAME_LEN before encoding
(so a >256 MiB message is rejected without allocating it).
Message-oriented transports (e.g. a WebSocket, where the message boundary is
the frame) use this directly instead of write_frame: they send the bytes
with no length prefix but still need the same oversize guard so the wire size
cap is identical across transports.
pub fn exceeds_max_frame_len(msg: &impl Message) -> Option<u32>;
The encoded frame length of msg when it exceeds MAX_FRAME_LEN
(saturating at u32::MAX), or None when it fits.
write_frame rejects an oversize frame anyway, but only once the caller
is committed to sending. Peers that must not mutate their own state until
the frame is known sendable — a parent about to mark a suspension answered,
a child about to enter one — check it with this first.
pub fn write_frame(writer: &mut impl Write, msg: &impl Message) -> Result<(), FrameError>;
Encodes msg and writes it to writer as one length-prefixed frame, then
flushes (see the module docs for why flushing every frame is required).
Frames above MAX_FRAME_LEN fail with FrameError::FrameTooLarge
before anything is written, keeping the stream in sync so the caller
can degrade gracefully instead of desynchronizing the protocol.
pub mod pb;
pub mod monty_node;
Nested message and enum types in MontyNode.
pub enum Kind {
Ellipsis(Unit),
None(Unit),
NotImplemented(Unit),
Boolean(bool),
/// Python int fitting in 64 bits.
Int(i64),
/// Python int wider than 64 bits.
Bigint(BigInt),
Float(f64),
Str(String),
Bytes(Vec<u8>),
/// A uuid.UUID value. Declared so the tag is settled, but NOT YET
/// IMPLEMENTED: monty has no uuid module, so neither end produces or
/// accepts this arm (conversion to a domain node rejects it).
Uuid(Uuid),
List(WireIndexes),
Tuple(WireIndexes),
NamedTuple(WireNamedTuple),
Dict(WireNodePairs),
Set(WireIndexes),
FrozenSet(WireIndexes),
Date(Date),
Time(Time),
Datetime(DateTime),
Timedelta(TimeDelta),
Timezone(TimeZone),
/// A simple exception VALUE (no traceback) — e.g. an exception stored in a
/// variable. Errors that terminate execution use `RaisedException` instead.
Exception(Exception),
/// A Python type object — builtin, sandbox class, or host class. A class
/// is a node of its own, shared by every instance of it in the arena.
Type(Type),
ClassInstance(ClassInstanceNode),
Function(Function),
/// A builtin function, named by its Python name, e.g. "len", "print".
BuiltinFunction(String),
/// A pathlib.Path value (always a virtual POSIX path, never a host path).
Path(String),
FileHandle(FileHandle),
/// OUTPUT-ONLY fallback: repr() of a value with no other representation.
Repr(String),
/// OUTPUT-ONLY: a reference back to a container enclosing this node, as
/// the placeholder its repr shows ("\[...\]", "(...)", "{...}" or "...").
Cycle(String),
}
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Kind>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Debug, PartialEq, StructuralPartialEq.
pub mod exc_data;
Nested message and enum types in ExcData.
pub enum Kind {
Unicode(UnicodeErrorData),
Json(JsonErrorData),
}
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Kind>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Debug, Eq, Hash, PartialEq, StructuralPartialEq.
pub mod unicode_error_data;
Nested message and enum types in UnicodeErrorData.
pub enum Object {
ObjectBytes(Vec<u8>),
ObjectStr(String),
}
The input that failed: bytes for decode errors, str for encode errors.
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Object>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Debug, Eq, Hash, PartialEq, StructuralPartialEq.
pub mod os_policy;
Nested message and enum types in OsPolicy.
pub enum Datetime {
/// The child's clock.
System(Unit),
/// Suspend to the parent's OS handler.
CallHost(Unit),
/// One frozen instant, for reproducible runs.
Fixed(FixedDateTime),
}
The instant date.today(), datetime.now() and time.time() read.
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Datetime>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Copy, Debug, Eq, Hash, PartialEq, StructuralPartialEq.
pub enum RandomStart {
/// From the child's own OS entropy.
RandomSystem(Unit),
/// Suspend the first draw with an `os.urandom` call for 2496 bytes.
RandomCallHost(Unit),
/// As `random.seed(seed)` would, for reproducible runs.
Seed(RandomSeed),
}
Where an unseeded random generator gets its first state.
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<RandomStart>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Debug, PartialEq, StructuralPartialEq.
pub enum ProcessTime {
/// Always 0.0, so elapsed execution time is not observable in the sandbox.
Zero(Unit),
/// The session's accumulated execution time.
Elapsed(Unit),
}
What time.process_time() and time.thread_time() report.
Absent (or with no arm set) = zero.
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<ProcessTime>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Copy, Debug, Eq, Hash, PartialEq, StructuralPartialEq.
pub mod sandbox_time_zone;
Nested message and enum types in SandboxTimeZone.
pub enum Zone {
/// UTC, the default.
Utc(Unit),
/// An IANA zone name (`Europe/London`), resolved from the child's tz database.
Named(String),
/// A fixed offset from UTC, with a name if it has one.
Fixed(TimeZone),
}
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Zone>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Debug, Eq, Hash, PartialEq, StructuralPartialEq.
pub mod sleep_mode;
Nested message and enum types in SleepMode.
pub enum Mode {
/// The parent waits without invoking its OS handler.
System(SystemSleep),
/// Suspend to the parent, which performs the wait.
CallHost(Unit),
/// Return at once without waiting.
Zero(Unit),
}
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Mode>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Copy, Debug, Eq, Hash, PartialEq, StructuralPartialEq.
pub mod random_seed;
Nested message and enum types in RandomSeed.
pub enum Value {
/// Arbitrary-size two's-complement little-endian bytes (`BigInt::to_signed_bytes_le`).
Int(Vec<u8>),
/// Must be finite.
Float(f64),
Str(String),
Bytes(Vec<u8>),
}
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Value>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Debug, PartialEq, StructuralPartialEq.
pub mod ext_function_result;
Nested message and enum types in ExtFunctionResult.
pub enum Kind {
/// The call returned this value: an index into the carrying message's
/// `values` arena.
ReturnValue(u32),
/// The call raised this exception.
Error(RaisedException),
/// The call is asynchronous: register an external future for `call_id`
/// (the id from the suspension event) and keep executing other tasks.
Future(u32),
/// No handler exists for this name — the child raises NameError.
NotFound(String),
/// No handler accepted this OS call — the child raises the call's own
/// no-handler default (PermissionError naming the path for filesystem
/// calls, RuntimeError for the rest). Only valid answering an `OsCall`
/// suspension; the child computes it from its retained call payload.
NotHandled(Unit),
}
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Kind>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Debug, PartialEq, StructuralPartialEq.
pub mod parent_request;
Nested message and enum types in ParentRequest.
pub enum Kind {
Configure(Configure),
InstallDependencies(InstallDependencies),
Feed(Feed),
ResumeCall(ResumeCall),
ResumeNameLookup(ResumeNameLookup),
ResumeFutures(ResumeFutures),
Dump(Dump),
Load(Load),
Reset(Reset),
Shutdown(Shutdown),
AbortFeed(AbortFeed),
}
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Kind>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Debug, PartialEq, StructuralPartialEq.
pub mod resume_name_lookup;
Nested message and enum types in ResumeNameLookup.
pub enum Kind {
/// The name resolves to this value: an index into `values`.
Value(u32),
/// The name is undefined — the child raises NameError (AttributeError for
/// a lazy attribute lookup).
Undefined(Unit),
/// Resolving the name raised on the parent — the child raises this
/// exception where the lookup suspended, bypassing hasattr()/getattr()
/// defaults.
Error(RaisedException),
}
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Kind>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Debug, PartialEq, StructuralPartialEq.
pub mod child_event;
Nested message and enum types in ChildEvent.
pub enum Kind {
Print(Print),
FunctionCall(WireFunctionCall),
OsCall(OsCall),
NameLookup(NameLookup),
ResolveFutures(ResolveFutures),
Complete(Complete),
Error(Error),
TypingError(TypingError),
DumpResult(DumpResult),
Ok(Ok),
FatalError(FatalError),
Shutdown(ShutdownDump),
}
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Kind>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Debug, PartialEq, StructuralPartialEq.
pub mod os_call;
Nested message and enum types in OsCall.
pub struct TextWrite {
pub path: String,
pub data: String,
}
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct BytesWrite {
pub path: String,
pub data: Vec<u8>,
}
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Open {
pub path: String,
/// Canonical open() mode string, same set as `FileHandle.mode`.
pub mode: String,
}
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Mkdir {
pub path: String,
pub parents: bool,
pub exist_ok: bool,
}
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Rename {
pub src: String,
pub dst: String,
}
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Getenv {
pub key: String,
pub default: u32,
}
os.getenv(key, default) — default may be any Python value: an index
into the enclosing OsCall.values.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct TimeCall {
pub caller: String,
}
A time-module clock read. caller names the Python function that asked
(time.time, time.monotonic, …), so a parent may answer them
differently; they all share the time.time call name.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct DateTimeNow {
/// Fixed-offset timezone for an aware result; absent for a naive one.
pub tz: ::core::option::Option<TimeZone>,
}
datetime.now(tz) — the VM validates the argument to None-or-timezone before suspending, so the wire carries a typed TimeZone rather than an arbitrary MontyObject.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Urandom {
pub size: u64,
}
os.urandom(size) — the byte count the sandbox validated; unsigned so a negative count cannot be expressed on the wire.
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Sleep {
/// How long to wait. Always finite, non-negative, and small enough to be a
/// duration of nanoseconds in an int64; a frame breaking that is rejected.
pub seconds: f64,
}
time.sleep(seconds) — the parent waits, then answers (the sandbox evaluates the call to None whatever the answer carried). Answering with a future is refused: the call is a block by definition.
Implements: Clone, Copy, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct AsyncSleep {
/// How long to wait, under the same constraints as `Sleep.seconds`.
pub delay: f64,
}
asyncio.sleep(delay) — the awaitable form. A parent running an event
loop should answer ExtFunctionResult.future and resolve it once the
delay elapses, so the sandbox’s other tasks keep running; answering
directly is equivalent to a wait that blocks them. The answer’s value is
ignored: the sandbox keeps the result argument itself and produces it
from the await.
Implements: Clone, Copy, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub enum Call {
/// ---- FS read / check / remove — the string is the virtual path -------
///
/// Path.exists
Exists(String),
/// Path.is_file
IsFile(String),
/// Path.is_dir
IsDir(String),
/// Path.is_symlink
IsSymlink(String),
/// Path.read_text
ReadText(String),
/// Path.read_bytes
ReadBytes(String),
/// Path.stat
Stat(String),
/// Path.iterdir
Iterdir(String),
/// Path.resolve
Resolve(String),
/// Path.absolute
Absolute(String),
/// Path.unlink
Unlink(String),
/// Path.rmdir
Rmdir(String),
/// ---- FS write / mutate -----------------------------------------------
///
/// Path.write_text (truncating)
WriteText(TextWrite),
/// Path.append_text
AppendText(TextWrite),
/// Path.write_bytes (truncating)
WriteBytes(BytesWrite),
/// Path.append_bytes
AppendBytes(BytesWrite),
Open(Open),
Mkdir(Mkdir),
Rename(Rename),
/// ---- Non-FS ----------------------------------------------------------
///
/// os.getenv
Getenv(Getenv),
/// the os.environ snapshot
GetEnviron(Unit),
/// date.today()
DateToday(Unit),
/// datetime.now(tz) — the timezone argument (absent for a naive result).
DateTimeNow(DateTimeNow),
/// os.urandom(size), also how `random` seeds an unseeded generator.
Urandom(Urandom),
/// time.time() and the other time-module clock reads
Time(TimeCall),
/// time.sleep(seconds) under `call_host`: the handler waits
Sleep(Sleep),
/// asyncio.sleep(delay) under `call_host`
AsyncSleep(AsyncSleep),
/// System sleeps: capped by the child, charged to `max_total_sleep` and
/// waited out by the parent without invoking its OS handler.
SystemSleep(Sleep),
AsyncSystemSleep(AsyncSleep),
}
pub fn encode(&self, buf: &mut impl BufMut)
Encodes the message to a buffer.
pub fn merge(
field: &mut ::core::option::Option<Call>,
tag: u32,
wire_type: WireType,
buf: &mut impl Buf,
ctx: DecodeContext,
) -> ::core::result::Result<(), DecodeError>
Decodes an instance of the message from a buffer, and merges it into self.
pub fn encoded_len(&self) -> usize
Returns the encoded length of the message without a length delimiter.
Implements: Clone, Debug, PartialEq, StructuralPartialEq, TryFrom<Call>.
pub struct Unit { /* private fields */ }
Empty placeholder for valueless oneof arms. Defined locally (rather than importing google.protobuf.Empty) so non-Rust decoders need nothing beyond this single file.
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct MontyNode {
pub kind: ::core::option::Option<monty_node::Kind>,
}
One node of an Arena. Leaf arms carry the value; container arms carry
the indexes of their children.
repr and cycle are OUTPUT-ONLY: the child may emit them (e.g. inside a
Complete value) but rejects them as inputs.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct NodePair {
pub key: u32,
pub value: u32,
}
One key/value entry as node indexes. Used for dicts, attrs and kwargs: proto maps cannot have message keys and do not preserve order, while Python dicts allow arbitrary hashable keys and are insertion-ordered.
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct BigInt {
pub negative: bool,
pub magnitude: Vec<u8>,
}
Arbitrary-precision integer as sign + big-endian magnitude. Exact and O(n);
JS decode is (negative ? -1n : 1n) * BigInt('0x' + hex(magnitude)).
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Date {
/// Gregorian year in 1..=9999.
pub year: i32,
/// 1..=12.
pub month: u32,
pub day: u32,
}
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct DateTime {
pub year: i32,
pub month: u32,
pub day: u32,
pub hour: u32,
pub minute: u32,
pub second: u32,
/// 0..=999999.
pub microsecond: u32,
/// Fixed UTC offset for aware datetimes; absent for naive values.
pub offset_seconds: ::core::option::Option<i32>,
/// Optional timezone name; only valid when offset_seconds is set.
pub timezone_name: ::core::option::Option<String>,
}
pub fn offset_seconds(&self) -> i32
Returns the value of offset_seconds, or the default value if offset_seconds is unset.
pub fn timezone_name(&self) -> &str
Returns the value of timezone_name, or the default value if timezone_name is unset.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Time {
/// 0..=23.
pub hour: u32,
/// 0..=59.
pub minute: u32,
/// 0..=59.
pub second: u32,
/// 0..=999999.
pub microsecond: u32,
/// Fixed UTC offset for aware times; absent for naive values.
pub offset_seconds: ::core::option::Option<i32>,
/// Optional timezone name; only valid when offset_seconds is set.
pub timezone_name: ::core::option::Option<String>,
/// Disambiguates a repeated wall clock, 0 or 1. Carried so a time does not
/// silently lose the flag crossing the boundary; monty never interprets it.
pub fold: u32,
}
pub fn offset_seconds(&self) -> i32
Returns the value of offset_seconds, or the default value if offset_seconds is unset.
pub fn timezone_name(&self) -> &str
Returns the value of timezone_name, or the default value if timezone_name is unset.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct TimeDelta {
pub days: i32,
/// Normalized to 0..86400.
pub seconds: i32,
/// Normalized to 0..1000000.
pub microseconds: i32,
}
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct TimeZone {
pub offset_seconds: i32,
pub name: ::core::option::Option<String>,
}
pub fn name(&self) -> &str
Returns the value of name, or the default value if name is unset.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Exception {
pub exc_type: String,
pub arg: ::core::option::Option<String>,
}
A simple exception value: type name (e.g. “ValueError”) + optional single string argument.
pub fn arg(&self) -> &str
Returns the value of arg, or the default value if arg is unset.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct FileHandle {
/// Virtual (sandbox) path — never a host path.
pub path: String,
/// Canonical Python open() mode string: one of r, rb, r+, rb+, w, wb, w+,
/// wb+, a, ab, a+, ab+.
pub mode: String,
/// Char index (text mode) or byte index (binary mode).
pub position: u64,
}
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Uuid {
pub data: Vec<u8>,
}
A 16-byte UUID (uuid4). Exactly 16 bytes; validated on decode. Class and
instance ids are generated by whichever side defined the object, so they never
encode a memory address and cannot be reused the way CPython reuses id().
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Type {
/// Python-visible name: builtin Display name ("int", "datetime.datetime")
/// or class name ("Point").
pub name: String,
/// Identity of the class; absent iff origin == TYPE_ORIGIN_BUILTIN.
pub id: ::core::option::Option<Uuid>,
/// Where the type was defined (builtin, sandbox, or host).
pub origin: i32,
/// Whether `dataclasses.is_dataclass` is true for the class.
pub is_dataclass: bool,
/// Class attributes sent eagerly with the type object (class constants, per
/// the sending wrapper's policy), as `(name, value)` node indexes. The
/// sandbox keeps one type object per class id: a non-empty set replaces its
/// attrs, an empty set leaves them unchanged. The worker never sends attrs
/// for a sandbox class.
pub attrs: ::core::option::Option<WireNodePairs>,
}
A Python type object crossing the sandbox boundary.
pub fn origin(&self) -> TypeOrigin
Returns the enum value of origin, or the default if the field is set to an invalid enum value.
pub fn set_origin(&mut self, value: TypeOrigin)
Sets origin to the provided enum value.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct ClassInstanceNode {
/// Index of the instance's class: a `type` node with origin SANDBOX or HOST
/// (never BUILTIN), shared by every instance of the class in the arena.
pub class_type: u32,
/// Identity of the instance, generated by whichever side defined it.
pub instance_id: ::core::option::Option<Uuid>,
/// Eagerly-sent attributes as `(name, value)` node indexes, in order.
pub attrs: ::core::option::Option<WireNodePairs>,
}
A class instance crossing the sandbox boundary. Host-backed instances route
method calls and lazy attribute lookups back to the real object by uuid
(FunctionCall.object_id / NameLookup.object_id); sandbox-defined
instances carry a worker-generated uuid instead.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct Function {
pub name: String,
pub docstring: ::core::option::Option<String>,
}
An external (host-provided) function value, usually supplied by the parent
in response to a NameLookup event.
pub fn docstring(&self) -> &str
Returns the value of docstring, or the default value if docstring is unset.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct RaisedException {
/// Exception type name, e.g. "ValueError", "json.JSONDecodeError".
pub exc_type: String,
pub message: ::core::option::Option<String>,
/// Outermost frame first, matching Python traceback order.
pub traceback: Vec<StackFrame>,
/// Structured payload for exception types that carry more than a message;
/// absent for most exceptions. Mirrors monty's `ExcData`.
pub data: ::core::option::Option<ExcData>,
}
A raised Python exception with its traceback. Mirrors monty’s
MontyException.
pub fn message(&self) -> &str
Returns the value of message, or the default value if message is unset.
Implements: Clone, Debug, Default, From<&MontyException>, Message, PartialEq, StructuralPartialEq, TryFrom<RaisedException>.
pub struct ExcData {
pub kind: ::core::option::Option<exc_data::Kind>,
}
Structured exception payload, mirroring monty’s ExcData enum. Future
exception types that carry more than a message (e.g. OSError’s errno)
get new oneof arms with fresh tags. An absent/empty kind means “no
payload” (ExcData::None).
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct UnicodeErrorData {
/// Codec name as CPython reports it, e.g. "utf-8".
pub encoding: String,
/// Failing range: byte offsets for decode errors, character indices for
/// encode errors. `end` is exclusive.
pub start: u64,
pub end: u64,
/// CPython's reason wording, e.g. "ordinal not in range(128)".
pub reason: String,
/// The input that failed: bytes for decode errors, str for encode errors.
pub object: ::core::option::Option<unicode_error_data::Object>,
}
CPython’s UnicodeDecodeError/UnicodeEncodeError constructor fields
(encoding, object, start, end, reason), letting hosts rebuild the real
exception instead of a message-only fallback. Mirrors monty’s
UnicodeErrorData.
Implements: Clone, Debug, Default, Eq, From<&UnicodeErrorData>, Hash, Message, PartialEq, StructuralPartialEq.
pub struct JsonErrorData {
/// Bare error message, without the ": line N column M (char K)" suffix.
pub msg: String,
/// The document being parsed; absent when larger than the sender's size cap
/// or when bytes input is not valid UTF-8.
pub doc: ::core::option::Option<String>,
/// Character index of the error in `doc`.
pub pos: u64,
/// 1-based line and column of the error.
pub lineno: u64,
pub colno: u64,
}
CPython’s json.JSONDecodeError attribute fields (msg, doc, pos, lineno,
colno), letting hosts rebuild the real exception instead of a message-only
fallback. Mirrors monty’s JsonErrorData.
pub fn doc(&self) -> &str
Returns the value of doc, or the default value if doc is unset.
Implements: Clone, Debug, Default, Eq, From<&JsonErrorData>, Hash, Message, PartialEq, StructuralPartialEq.
pub struct CodeLoc {
pub line: u32,
pub column: u32,
}
1-based line/column source position (columns count characters, not bytes).
Implements: Clone, Copy, Debug, Default, Eq, From<CodeLoc>, Hash, Message, PartialEq, StructuralPartialEq.
pub struct StackFrame {
pub filename: String,
pub start: ::core::option::Option<CodeLoc>,
pub end: ::core::option::Option<CodeLoc>,
/// Function name; absent for module-level code (rendered as "<module>").
pub frame_name: ::core::option::Option<String>,
/// Source line shown in the traceback preview.
pub preview_line: ::core::option::Option<String>,
/// Suppress the `~~~` caret markers for this frame.
pub hide_caret: bool,
/// Suppress the `, in <name>` suffix (SyntaxError style).
pub hide_frame_name: bool,
}
pub fn frame_name(&self) -> &str
Returns the value of frame_name, or the default value if frame_name is unset.
pub fn preview_line(&self) -> &str
Returns the value of preview_line, or the default value if preview_line is unset.
Implements: Clone, Debug, Default, Eq, From<&StackFrame>, Hash, Message, PartialEq, StructuralPartialEq, TryFrom<StackFrame>.
pub struct ResourceLimits {
pub max_memory_bytes: ::core::option::Option<u64>,
pub gc_interval: ::core::option::Option<u64>,
pub max_recursion_depth: ::core::option::Option<u64>,
pub max_suspensions: ::core::option::Option<u64>,
/// Per-feed and per-turn execution budgets on one clock: the feed budget
/// resets at each feed, the turn budget at each feed and each resume.
pub max_feed_duration_micros: ::core::option::Option<u64>,
pub max_turn_duration_micros: ::core::option::Option<u64>,
/// Cumulative budget for system sleeps, enforced by the parent.
pub max_total_sleep_micros: ::core::option::Option<u64>,
}
Sandbox resource limits. Absent fields are unlimited except recursion depth
and max_suspensions, which both default to 1000. The parent enforces
max_suspensions; the child only retains it for dumps and echoes it on
ChildEvent.
pub fn max_memory_bytes(&self) -> u64
Returns the value of max_memory_bytes, or the default value if max_memory_bytes is unset.
pub fn gc_interval(&self) -> u64
Returns the value of gc_interval, or the default value if gc_interval is unset.
pub fn max_recursion_depth(&self) -> u64
Returns the value of max_recursion_depth, or the default value if max_recursion_depth is unset.
pub fn max_suspensions(&self) -> u64
Returns the value of max_suspensions, or the default value if max_suspensions is unset.
pub fn max_feed_duration_micros(&self) -> u64
Returns the value of max_feed_duration_micros, or the default value if max_feed_duration_micros is unset.
pub fn max_turn_duration_micros(&self) -> u64
Returns the value of max_turn_duration_micros, or the default value if max_turn_duration_micros is unset.
pub fn max_total_sleep_micros(&self) -> u64
Returns the value of max_total_sleep_micros, or the default value if max_total_sleep_micros is unset.
Implements: Clone, Copy, Debug, Default, Eq, From<&ResourceLimits>, From<ResourceLimits>, Hash, Message, PartialEq, StructuralPartialEq.
pub struct OsPolicy {
/// The zone naive `datetime.now()` and `date.today()` read in, and that
/// `astimezone()`, `%Z` and the `time` constants report. Absent = UTC.
pub timezone: ::core::option::Option<SandboxTimeZone>,
/// What `time.sleep()` and `asyncio.sleep()` do.
/// Absent (or with no arm set) = system sleep with the default maximum.
pub sleep: ::core::option::Option<SleepMode>,
/// The instant `date.today()`, `datetime.now()` and `time.time()` read.
pub datetime: ::core::option::Option<os_policy::Datetime>,
/// Where an unseeded `random` generator gets its first state.
pub random_start: ::core::option::Option<os_policy::RandomStart>,
/// What `time.process_time()` and `time.thread_time()` report.
/// Absent (or with no arm set) = zero.
pub process_time: ::core::option::Option<os_policy::ProcessTime>,
}
Mirrors monty’s OsPolicy: the clock, zone, sleep, process clock and
initial randomness a session gets, and which of those it asks the host for.
Each unset arm means that field’s default.
Implements: Clone, Debug, Default, From<&OsPolicy>, Message, PartialEq, StructuralPartialEq, TryFrom<OsPolicy>.
pub struct SandboxTimeZone {
pub zone: ::core::option::Option<sandbox_time_zone::Zone>,
}
Mirrors monty’s SandboxTimeZone.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct SleepMode {
pub mode: ::core::option::Option<sleep_mode::Mode>,
}
Mirrors monty’s SleepMode.
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct SystemSleep {
/// Longest wait one call performs; longer sleeps are cut short. Absent = 10s.
pub max_micros: ::core::option::Option<u64>,
}
A sleep capped by the child and performed by the parent.
pub fn max_micros(&self) -> u64
Returns the value of max_micros, or the default value if max_micros is unset.
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct FixedDateTime {
/// Seconds since the Unix epoch, UTC.
pub unix_seconds: i64,
/// 0..=999999; anything larger is rejected.
pub microsecond: u32,
}
A frozen clock reading.
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct RandomSeed {
pub value: ::core::option::Option<random_seed::Value>,
}
A random.seed() argument: the types CPython accepts.
Implements: Clone, Debug, Default, From<&RandomSeed>, Message, PartialEq, StructuralPartialEq, TryFrom<RandomSeed>.
pub struct ExtFunctionResult {
pub kind: ::core::option::Option<ext_function_result::Kind>,
}
Outcome of an external function / OS call, decided by the parent. Mirrors
monty’s ExtFunctionResult, plus not_handled (which only the child can
resolve, against its suspended call).
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct FutureResult {
pub call_id: u32,
pub result: ::core::option::Option<ExtFunctionResult>,
}
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct NamedRef {
pub name: String,
pub value: u32,
}
A named input: value indexes the carrying message’s values arena.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct ParentRequest {
/// W3C `traceparent` identifying the caller's span, so a child that exports
/// its own telemetry can attach its spans to the trace the request came
/// from. Purely additive context: the child's execution of the request must
/// not depend on it, and it is absent whenever the parent is not tracing.
pub trace_parent: ::core::option::Option<String>,
pub kind: ::core::option::Option<parent_request::Kind>,
}
Tags 1-19 are reserved for kind arms and the message-level fields start
at 20, mirroring ChildEvent — a oneof shares its field-number space with
the enclosing message, so a new arm never has to jump the numbering. The
same caveats apply: arms past 15 cost a two-byte key, and a forwarding
server mirrors this numbering to classify frames without decoding them, so
adding an arm degrades to “opaque” while renumbering one would misroute.
pub fn trace_parent(&self) -> &str
Returns the value of trace_parent, or the default value if trace_parent is unset.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct Configure {
pub script_name: String,
pub limits: ::core::option::Option<ResourceLimits>,
/// Type-check each fed snippet before executing it.
pub type_check: bool,
/// Optional stub file contents used by type checking.
pub type_check_stubs: ::core::option::Option<String>,
/// The parent's monty package version (e.g. "0.0.18"). INFORMATIONAL ONLY —
/// it is never checked, only reported (in telemetry, and when diagnosing a
/// rejected `protocol_version`). Parent and child may run different package
/// versions as long as their protocol versions are compatible.
pub monty_version: String,
/// Introspected `assert` failure messages (see limitations/assert.md).
/// Absent = on with the default 120-byte operand-repr truncation; 0 disables
/// annotations; any other value retains that many bytes per operand before
/// any ellipsis, cutting on a character boundary.
pub assert_message_annotations: ::core::option::Option<u32>,
/// How the child renders the diagnostics carried by `TypingError`. The
/// structured diagnostics borrow the type checker's database and so cannot
/// cross the wire — the parent picks the format up front and the child
/// renders it. Ignored when `type_check` is false.
pub type_check_format: i32,
/// Render typing diagnostics with ANSI colour escapes. Only `FULL` and
/// `CONCISE` carry colour; the machine-readable formats ignore it.
pub type_check_color: bool,
/// Version of the wire schema the parent speaks. The child rejects the
/// session with a `FatalError` naming its own supported range when this
/// falls outside it, so a parent deployed separately from its worker (over
/// a websocket, say) learns what to downgrade to without a handshake.
///
/// 0 means the parent declared nothing — either it predates this field or it
/// is not a monty parent — and is always rejected. The protocol has no
/// in-band negotiation, so an undeclared peer cannot be assumed compatible.
pub protocol_version: u32,
/// How long the child may hold buffered `print()` output before emitting it
/// as a `Print` event, in milliseconds. Absent means the child's default
/// (`DEFAULT_PRINT_FLUSH_INTERVAL`). 0 disables the timer and restores line
/// buffering — one event per completed line, as before this field existed —
/// for a host that wants each `print()` delivered on its own.
///
/// Output is always flushed before a turn-ending event whatever this says, so
/// the field trades streaming latency for event volume and nothing else.
pub print_flush_interval_ms: ::core::option::Option<u32>,
/// Absent = `OsPolicy::default()`: the child's clock in UTC and its entropy,
/// with parent-serviced sleeps capped at 10s. `Load` restores the dump's settings.
pub os_policy: ::core::option::Option<OsPolicy>,
}
Configures the REPL session this child will serve until Reset, sent once
when the worker is checked out. The session’s repl is materialized lazily on
the first Feed (or restored by Load), so a checked-out-but-unfed
worker can still be initialized by Load instead. Valid only when the
worker has no session yet.
pub fn type_check_stubs(&self) -> &str
Returns the value of type_check_stubs, or the default value if type_check_stubs is unset.
pub fn assert_message_annotations(&self) -> u32
Returns the value of assert_message_annotations, or the default value if assert_message_annotations is unset.
pub fn type_check_format(&self) -> TypeCheckFormat
Returns the enum value of type_check_format, or the default if the field is set to an invalid enum value.
pub fn set_type_check_format(&mut self, value: TypeCheckFormat)
Sets type_check_format to the provided enum value.
pub fn print_flush_interval_ms(&self) -> u32
Returns the value of print_flush_interval_ms, or the default value if print_flush_interval_ms is unset.
Implements: Clone, Debug, Default, From<&Configure>, Message, PartialEq, StructuralPartialEq.
pub struct Feed {
pub code: String,
/// Inputs, each an index into `values`; one arena, so an object passed
/// under two names is one sandbox object.
pub inputs: Vec<NamedRef>,
pub values: ::core::option::Option<WireArena>,
/// Skip type checking for this feed even when the session enables it.
pub skip_type_check: bool,
/// Absolute virtual working directory to switch the session to before the
/// feed, resolved by the parent (an explicit choice, or the first mount on
/// the session's first feed). Empty keeps the session's current directory.
pub cwd: String,
}
Executes one snippet against the session. Turn ends with Complete,
Error, TypingError, or a suspension event.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct AbortFeed {
pub exception: ::core::option::Option<RaisedException>,
}
Ends a pending suspension by raising exception uncatchably at its site.
The session returns ready in an Error event. Hosts use this to stop a feed,
including when max_suspensions is exceeded.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct ResumeCall {
pub call_id: u32,
pub result: ::core::option::Option<ExtFunctionResult>,
/// The arena `result.return_value` indexes.
pub values: ::core::option::Option<WireArena>,
}
Answers a FunctionCall or OsCall suspension. call_id must match the
suspension event.
Implements: Clone, Debug, Default, From<MontyObject>, Message, PartialEq, StructuralPartialEq.
pub struct ResumeNameLookup {
/// The arena `value` indexes.
pub values: ::core::option::Option<WireArena>,
pub kind: ::core::option::Option<resume_name_lookup::Kind>,
}
Answers a NameLookup suspension.
Implements: Clone, Debug, Default, From<NameLookupResult>, Message, PartialEq, StructuralPartialEq, TryFrom<ResumeNameLookup>.
pub struct ResumeFutures {
/// Also answers an eager FunctionCall with exactly one result matching its
/// call_id. The worker creates a settled awaitable before continuing.
pub results: Vec<FutureResult>,
/// The arena every `return_value` indexes.
pub values: ::core::option::Option<WireArena>,
}
Answers a ResolveFutures suspension with results for some or all pending
call ids.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct Dump { /* private fields */ }
Requests an opaque serialized snapshot of the current session state
(idle or suspended). The child stays usable afterwards. The bytes carry
monty’s own dump format, versioned independently of this schema, and can
only be restored via Load by a child built with the same dump version.
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Load {
pub state: Vec<u8>,
}
Restores state produced by Dump. Valid only from no session. If
the restored state was suspended, the child re-emits the suspension event so
the parent learns the resume point; otherwise it replies Ok.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Reset { /* private fields */ }
Ends the checkout: the child drops all session state and returns to the
no-session state, ready for the next Configure or Load.
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Shutdown { /* private fields */ }
The child replies Ok and exits cleanly.
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct InstallDependencies {
/// PEP 508 requirement strings, e.g. "httpx>=0.27", "numpy". An empty list is
/// a no-op that replies `Ok`.
pub requirements: Vec<String>,
}
Installs third-party Python packages into the session before further feeds,
using uv pip install --python <venv-python> against the worker’s session
virtualenv. Only the
embedded-CPython worker honors this; the Monty sandbox child rejects it with
an Error (it has no host interpreter to install for). Repeatable between
feeds. Turn ends with Ok on success or Error (carrying uv’s stderr) on
failure. Valid only once a session exists (after Configure).
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct ChildEvent {
/// Cumulative execution time consumed by the session's sandbox code, in
/// microseconds. The in-sandbox clock runs only while the interpreter is
/// executing bytecode — never while suspended waiting on the parent or idle
/// between feeds — and survives Dump/Load. Set on every turn-ending event
/// while a session exists (zero on Print events and outside a session) so
/// the parent can report how much sandbox time a session has used without
/// keeping a second clock. Bounds nothing: the budgets are per-feed and
/// per-turn.
pub total_execution_micros: u64,
/// Echoes the parent-enforced budget so a host restoring an opaque dump can
/// recover it.
pub max_suspensions: ::core::option::Option<u64>,
/// Execution time consumed by the feed in progress, in microseconds — the
/// `total_execution_micros` clock restarted at the feed that is running.
/// Lets the parent backstop `max_feed_duration_micros` without tracking feed
/// boundaries against a clock it cannot see. Zero outside a session.
pub feed_execution_micros: u64,
/// The session's `max_feed_duration` and `max_turn_duration` limits in
/// microseconds, when configured. Reported so a parent that restored a
/// session via `Load` (where the limits travel inside the opaque state
/// bytes) still learns its budgets.
pub max_feed_duration_micros: ::core::option::Option<u64>,
pub max_turn_duration_micros: ::core::option::Option<u64>,
/// Parent-enforced sleep budget, also reported on `Load`.
pub max_total_sleep_micros: ::core::option::Option<u64>,
/// The session's script name, surfaced on a `Load` reply so a parent that
/// restored a session (whose script name, like the limits above, travels
/// inside the opaque dump bytes) learns it without parsing the dump. Set only
/// on a successful `Load` reply; unset on all other events.
pub restored_script_name: ::core::option::Option<String>,
pub kind: ::core::option::Option<child_event::Kind>,
}
A oneof shares its field-number space with the enclosing message, so tags
1-19 are reserved by convention for kind arms and the message-level
fields start at 20 — a new arm then never has to jump the numbering. Note
arms past 15 cost a two-byte key instead of one, which forwarding servers
(which walk only field keys, on every frame) pay per event. Such a server
mirrors this numbering to classify frames without decoding them; it treats
a tag it does not know as opaque, so adding an arm degrades rather than
misroutes, but renumbering an existing one would break it.
pub fn max_suspensions(&self) -> u64
Returns the value of max_suspensions, or the default value if max_suspensions is unset.
pub fn restored_script_name(&self) -> &str
Returns the value of restored_script_name, or the default value if restored_script_name is unset.
pub fn max_feed_duration_micros(&self) -> u64
Returns the value of max_feed_duration_micros, or the default value if max_feed_duration_micros is unset.
pub fn max_turn_duration_micros(&self) -> u64
Returns the value of max_turn_duration_micros, or the default value if max_turn_duration_micros is unset.
pub fn max_total_sleep_micros(&self) -> u64
Returns the value of max_total_sleep_micros, or the default value if max_total_sleep_micros is unset.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct PrintSegment {
pub stream: i32,
pub text: String,
}
One run of print() output on a single stream, as one Print event may
carry several.
pub fn stream(&self) -> PrintStream
Returns the enum value of stream, or the default if the field is set to an invalid enum value.
pub fn set_stream(&mut self, value: PrintStream)
Sets stream to the provided enum value.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Print {
pub segments: Vec<PrintSegment>,
}
Streamed sandbox print() output. Zero or more of these precede each turn-ending event, and each carries the runs the worker had buffered, in the order the sandbox produced them — so output alternating between the streams batches into one event without losing that order.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct OsCall {
pub call_id: u32,
/// The arena any value-typed argument (`Getenv.default`) indexes.
pub values: ::core::option::Option<WireArena>,
/// As on `FunctionCall`: the parent may await a coroutine and answer with
/// `ResumeFutures` for `call_id`. Only ever set on `async_sleep`, the one
/// call a future may answer at all.
pub allow_eager_await: bool,
pub call: ::core::option::Option<os_call::Call>,
}
Suspension: the sandbox performed an OS operation, surfaced for the parent
to service (e.g. from a mount) or answer with ResumeCall. One typed arm
per call; every path is a virtual POSIX sandbox path, never a host path.
Some calls have typed result expectations (e.g. open must return a
file_handle); a mismatched result becomes a Python-level error inside the
sandbox.
A parent with no handler should answer ResumeCall with
ExtFunctionResult.not_handled: the child raises the call’s own default
(PermissionError naming the path for filesystem calls, RuntimeError for
the rest — monty’s OsFunctionCall::on_no_handler).
Tags 2-49 are reserved for call arms and the other message-level fields
start at 50, as in ChildEvent, so a new call never has to jump the numbering.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct NameLookup {
pub name: String,
/// Set for attribute lookups on a host-backed object — a class instance, or
/// a class type (a lazy class attribute): the uuid of the receiver.
pub object_id: ::core::option::Option<Uuid>,
}
Suspension: the sandbox read an undefined name — typically probing whether
the parent provides an external function — or, when object_id is set, a
lazy attribute lookup on a host-backed object. Answer with
ResumeNameLookup; for attribute lookups an undefined answer raises
AttributeError (not NameError) inside the sandbox.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct ResolveFutures {
pub pending_call_ids: Vec<u32>,
}
Suspension: every sandbox task is blocked on external futures previously
registered via ExtFunctionResult.future. Answer with ResumeFutures.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Complete {
/// Index of the result in `values`.
pub value: u32,
pub values: ::core::option::Option<WireArena>,
}
Turn end: the snippet completed with this value. The session is ready for
the next Feed.
Implements: Clone, Debug, Default, From<MontyObject>, Message, PartialEq, StructuralPartialEq, TryFrom<Complete>.
pub struct Error {
pub exception: ::core::option::Option<RaisedException>,
}
Turn end: the snippet (or request) failed with a Python exception. The session survives — prior globals remain available to later feeds.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct TypingError {
/// Diagnostics rendered in the session's `TypeCheckFormat`.
pub diagnostics: String,
}
Turn end: type checking rejected the fed snippet (only when the session was created with type_check). The snippet was not executed; the session survives.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct DumpResult {
/// Opaque versioned snapshot; see `Dump`.
pub state: Vec<u8>,
}
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct Ok { /* private fields */ }
Generic acknowledgement for Configure / Load (idle) / Reset / Shutdown.
Implements: Clone, Copy, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct FatalError {
pub message: String,
}
The child hit an unrecoverable error (frame desync, panic, unsupported protocol version) and exits immediately after writing this. A child that exits WITHOUT a FatalError crashed hard (segfault, abort, kill) — parents must treat EOF as a crash.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct ShutdownDump {
/// Session state captured immediately before shutdown (same bytes as
/// `DumpResult.state`), restorable into a fresh worker via `Load`. Absent
/// when there was no session yet or the dump itself failed.
pub dump: ::core::option::Option<Vec<u8>>,
}
Turn end: the serving relay (monty-server, never a child) is shutting down and did NOT run the request it is replying to. Sent only in reply to an in-flight request, so the client is always reading when it arrives.
Every other server policy action (idle/session/turn timeout, capacity) is just a dropped connection, which the client already classifies as a dead worker — only shutdown needs a message, because only shutdown has state to hand back.
pub fn dump(&self) -> &[u8]
Returns the value of dump, or the default value if dump is unset.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub enum TypeOrigin {
/// Rejected on decode.
Unspecified = 0,
/// `name` must parse as a known builtin type name ("int", "ValueError");
/// valid as an execution input. `id` must be absent. Kept distinct from
/// SANDBOX so a sandbox class shadowing a builtin name ("int") cannot be
/// confused with the builtin type.
Builtin = 1,
/// A sandbox-defined class; `id` required. Accepted by the decoder but
/// rejected as an execution input (the class binding cannot be
/// reconstructed host-side).
Sandbox = 2,
/// A host-defined class; `id` required.
Host = 3,
}
Where a Type comes from — drives id presence and input validation.
pub const fn is_valid(value: i32) -> bool
Returns true if value is a variant of TypeOrigin.
pub fn from_i32(value: i32) -> ::core::option::Option<TypeOrigin>
Deprecated. Use the TryFrom<i32> implementation instead
Converts an i32 to a TypeOrigin, or None if value is not a valid variant.
pub fn as_str_name(&self) -> &'static str
String value of the enum field names used in the ProtoBuf definition.
The values are not transformed in any way and thus are considered stable (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self>
Creates an enum from field names used in the ProtoBuf definition.
Implements: Clone, Copy, Debug, Default, Eq, From<TypeOrigin>, Hash, Ord, PartialEq, PartialOrd, StructuralPartialEq, TryFrom<i32>.
pub enum TypeCheckFormat {
/// Unset by an older parent — the child renders `FULL`.
Unspecified = 0,
Full = 1,
Concise = 2,
Azure = 3,
Json = 4,
JsonLines = 5,
Rdjson = 6,
Pylint = 7,
Gitlab = 8,
Github = 9,
}
Rendering of the typing diagnostics a TypingError carries; mirrors ty’s
DiagnosticFormat.
pub const fn is_valid(value: i32) -> bool
Returns true if value is a variant of TypeCheckFormat.
pub fn from_i32(value: i32) -> ::core::option::Option<TypeCheckFormat>
Deprecated. Use the TryFrom<i32> implementation instead
Converts an i32 to a TypeCheckFormat, or None if value is not a valid variant.
pub fn as_str_name(&self) -> &'static str
String value of the enum field names used in the ProtoBuf definition.
The values are not transformed in any way and thus are considered stable (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self>
Creates an enum from field names used in the ProtoBuf definition.
Implements: Clone, Copy, Debug, Default, Eq, From<TypeCheckFormat>, From<TypeCheckingFormat>, Hash, Ord, PartialEq, PartialOrd, StructuralPartialEq, TryFrom<i32>.
pub enum PrintStream {
Unspecified = 0,
Stdout = 1,
Stderr = 2,
}
pub const fn is_valid(value: i32) -> bool
Returns true if value is a variant of PrintStream.
pub fn from_i32(value: i32) -> ::core::option::Option<PrintStream>
Deprecated. Use the TryFrom<i32> implementation instead
Converts an i32 to a PrintStream, or None if value is not a valid variant.
pub fn as_str_name(&self) -> &'static str
String value of the enum field names used in the ProtoBuf definition.
The values are not transformed in any way and thus are considered stable (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self>
Creates an enum from field names used in the ProtoBuf definition.
Implements: Clone, Copy, Debug, Default, Eq, From<PrintStream>, Hash, Ord, PartialEq, PartialOrd, StructuralPartialEq, TryFrom<i32>.
pub fn validate_requirement(requirement: &str) -> Result<(), String>;
Rejects a requirement string that uv would interpret as a command-line option rather than a package specifier.
A valid PEP 508 requirement never begins with -, so a string that does
(e.g. --index-url=…, -r /etc/hosts, -e .) would be smuggled onto uv’s
command line as a flag. Empty/whitespace-only entries are also rejected
since uv has no use for them and they only signal caller confusion.
pub struct WireArena(pub BudgetVec<monty_types::unstable::MontyNode>);
The wire form of a MontyGraph: what the monty.v1.Arena proto message
decodes into and encodes from.
Decoding only collects nodes; Self::into_graph checks the arena
invariants (every child index lower than its holder, class instances
pointing at class nodes) once the whole message has arrived, since prost
has no end-of-message hook. Senders build it from a validated graph via From.
pub fn new(graph: MontyGraph) -> Self
Wraps a graph for sending. Equivalent to From, named for call sites
where .into() would be unclear.
pub fn into_graph(self) -> Result<MontyGraph, ProtoConvertError>
Validates the decoded nodes into a graph.
Implements: Clone, Debug, Default, From<MontyGraph>, Message, PartialEq, StructuralPartialEq.
pub struct WireFunctionCall {
/// Name of the external function the sandbox is calling.
pub function_name: String,
/// The arena `args` and `kwargs` index.
pub values: WireArena,
/// Positional arguments, in order.
pub args: BudgetVec<monty_types::unstable::NodeId>,
/// Keyword arguments as `(key, value)` ids, preserving wire order.
pub kwargs: BudgetVec<(monty_types::unstable::NodeId, monty_types::unstable::NodeId)>,
/// Child-assigned call id used by the matching resume request.
pub call_id: u32,
/// Uuid of the routed receiver (a host-backed instance, or a class type
/// for `__call__`/classmethod calls); `None` for plain external function
/// calls. The receiver is never included in `args`.
pub object_id: Option<monty_types::MontyUuid>,
/// The worker accepts an eagerly settled coroutine via `ResumeFutures`.
pub allow_eager_await: bool,
}
Wire form of monty.v1.FunctionCall: the call’s argument arena plus the
ids of its positional and keyword arguments.
Installed with prost_build::extern_path, so generated ChildEvent
decoding still handles the envelope while this payload keeps the argument
vectors as bare ids and uses WireArena’s incremental node decoding.
pub fn new(
function_name: String,
args: CallArgs,
call_id: u32,
object_id: Option<MontyUuid>,
allow_eager_await: bool,
) -> Self
Splits args into its arena and the id vectors the wire carries.
pub fn into_call_args(self) -> Result<CallArgs, ProtoConvertError>
Validates the decoded arena and argument ids into CallArgs.
Implements: Clone, Debug, Default, Message, PartialEq, StructuralPartialEq.
pub struct WireIndexes(pub BudgetVec<monty_types::unstable::NodeId>);
Wire Indexes stored as domain ids, avoiding an intermediate Vec<u32>.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct WireNamedTuple {
/// Name used when rendering the tuple.
pub type_name: String,
/// Ordered attribute names, one per value.
pub field_names: BudgetVec<String>,
/// Child ids, checked against the arena after decoding.
pub values: BudgetVec<monty_types::unstable::NodeId>,
}
Wire named tuple with domain ids and budgeted names, ready for zero-copy conversion.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.
pub struct WireNodePairs(pub BudgetVec<(monty_types::unstable::NodeId, monty_types::unstable::NodeId)>);
Wire NodePairs stored as domain pairs, with no intermediate pair vector.
Implements: Clone, Debug, Default, Eq, Hash, Message, PartialEq, StructuralPartialEq.