Skip to main content

Value & MontyObject

Value

Primary value type representing Python objects at runtime. This enum uses a hybrid design: small immediate values (Int, Bool, None) are stored inline, while heap-allocated values (List, Str, Dict, etc.) are stored in the arena and referenced via Ref(HeapId).
Clone is intentionally NOT derived. Use clone_with_heap() for heap values or clone_immediate() for immediate values only. Direct cloning via .clone() would bypass reference counting and cause memory leaks.

Variants

Undefined
Value
Internal undefined value marker
Ellipsis
Value
Python’s Ellipsis singleton (...)
None
Value
Python’s None singleton
Bool(bool)
Value
Python boolean (True or False)
Int(i64)
Value
Python integer (64-bit signed)
Float(f64)
Value
Python float (64-bit IEEE 754)
InternString(StringId)
Value
An interned string literal. The StringId references the string in the Interns table. To get the actual string content, use interns.get(string_id).
InternBytes(BytesId)
Value
An interned bytes literal. The BytesId references the bytes in the Interns table. To get the actual bytes content, use interns.get_bytes(bytes_id).
InternLongInt(LongIntId)
Value
An interned long integer literal. The LongIntId references the BigInt in the Interns table. Used for integer literals exceeding i64 range. Converted to heap-allocated LongInt on load.
Builtin(Builtins)
Value
A builtin function or exception type
ModuleFunction(ModuleFunctions)
Value
A function from a module (not a global builtin). Module functions require importing a module to access (e.g., asyncio.gather).
DefFunction(FunctionId)
Value
A function defined in the module (not a closure, doesn’t capture any variables)
ExtFunction(StringId)
Value
Reference to an external function defined on the host. The StringId stores the interned function name. When called, the VM yields a FrameExit::ExternalCall with this StringId so the host can look up and execute the function by name.
Marker(Marker)
Value
A marker value representing special objects like sys.stdout/stderr. These exist but have minimal functionality in the sandboxed environment.
Property(Property)
Value
A property descriptor that computes its value when accessed. When retrieved via py_getattr, the property’s getter is invoked.
ExternalFuture(CallId)
Value
A pending external function call result. Created when the host calls run_pending() instead of run(result) for an external function call. The CallId correlates with the call that created it. When awaited, blocks the task until the host provides a result via resume(). ExternalFutures follow single-shot semantics like coroutines - awaiting an already-awaited ExternalFuture raises RuntimeError.
Ref(HeapId)
Value
Heap-allocated values (stored in arena)

MontyObject

A Python value that can be passed to or returned from the interpreter. This is the public-facing type for Python values. It owns all its data and can be freely cloned, serialized, or stored. Unlike the internal Value type, MontyObject does not require a heap for operations.

Input vs Output Variants

Most variants can be used both as inputs (passed to run()) and outputs (returned from execution). However:
  • Repr is output-only: represents values that have no direct MontyObject mapping
  • Exception can be used as input (to raise) or output (when code raises)

Variants

Ellipsis
MontyObject
Python’s Ellipsis singleton (...)
None
MontyObject
Python’s None singleton
Bool(bool)
MontyObject
Python boolean (True or False)
Int(i64)
MontyObject
Python integer (64-bit signed)
BigInt(BigInt)
MontyObject
Python arbitrary-precision integer (larger than i64)
Float(f64)
MontyObject
Python float (64-bit IEEE 754)
String(String)
MontyObject
Python string (UTF-8)
Bytes(Vec<u8>)
MontyObject
Python bytes object
List(Vec<MontyObject>)
MontyObject
Python list (mutable sequence)
Tuple(Vec<MontyObject>)
MontyObject
Python tuple (immutable sequence)
NamedTuple
MontyObject
Python named tuple (immutable sequence with named fields). Named tuples behave like tuples but also support attribute access by field name.Fields:
  • type_name: String - Type name for repr (e.g., “os.stat_result”)
  • field_names: Vec<String> - Field names in order
  • values: Vec<MontyObject> - Values in order (same length as field_names)
Dict(DictPairs)
MontyObject
Python dictionary (insertion-ordered mapping)
Set(Vec<MontyObject>)
MontyObject
Python set (mutable, unordered collection of unique elements)
FrozenSet(Vec<MontyObject>)
MontyObject
Python frozenset (immutable, unordered collection of unique elements)
Exception
MontyObject
Python exception with type and optional message argumentFields:
  • exc_type: ExcType - The exception type (e.g., ValueError, TypeError)
  • arg: Option<String> - Optional string argument passed to the exception constructor
Type(Type)
MontyObject
A Python type object (e.g., int, str, list). Returned by the type() builtin and can be compared with other types.
BuiltinFunction(BuiltinsFunctions)
MontyObject
A builtin function reference
Path(String)
MontyObject
Python pathlib.Path object (or technically a PurePosixPath). Represents a filesystem path. Can be used both as input (from host) and output.
Dataclass
MontyObject
A dataclass instance with class name, field names, attributes, and mutabilityFields:
  • name: String - The class name (e.g., “Point”, “User”)
  • type_id: u64 - Identifier of the type, from id(type(dc)) in python
  • field_names: Vec<String> - Declared field names in definition order (for repr)
  • attrs: DictPairs - All attribute name → value mapping (includes fields and extra attrs)
  • frozen: bool - Whether this dataclass instance is immutable
Function
MontyObject
An external function provided by the host. Returned by the host in response to a NameLookup to provide a callable that the VM can invoke.Fields:
  • name: String - The function name (used for repr, error messages, and function call identification)
  • docstring: Option<String> - Optional docstring for the function
Repr(String)
MontyObject
Fallback for values that cannot be represented as other variants. Contains the repr() string of the original value. This is output-only and cannot be used as an input.
Cycle(HeapId, String)
MontyObject
Represents a cycle detected during Value-to-MontyObject conversion. When converting cyclic structures (e.g., a = []; a.append(a)), this variant is used to break the infinite recursion. Contains the heap ID and the type-specific placeholder string (e.g., "[...]" for lists, "{...}" for dicts). This is output-only.

Methods

py_repr()

Returns the Python repr() string for this value.
String
The repr string representation
use monty::MontyObject;

let obj = MontyObject::Int(42);
assert_eq!(obj.py_repr(), "42");

let obj = MontyObject::String("hello".to_owned());
assert_eq!(obj.py_repr(), "'hello'");

is_truthy()

Returns true if this value is “truthy” according to Python’s truth testing rules. In Python, the following values are considered falsy:
  • None and Ellipsis
  • False
  • Zero numeric values (0, 0.0)
  • Empty sequences and collections ("", b"", [], (), {})
All other values are truthy, including Exception and Repr variants.
bool
True if the value is truthy
use monty::MontyObject;

assert!(MontyObject::Int(42).is_truthy());
assert!(!MontyObject::Int(0).is_truthy());
assert!(MontyObject::String("hello".to_owned()).is_truthy());
assert!(!MontyObject::String("".to_owned()).is_truthy());

type_name()

Returns the Python type name for this value (e.g., "int", "str", "list"). These are the same names returned by Python’s type(x).__name__.
&'static str
The type name
use monty::MontyObject;

assert_eq!(MontyObject::Int(42).type_name(), "int");
assert_eq!(MontyObject::String("hello".to_owned()).type_name(), "str");
assert_eq!(MontyObject::List(vec![]).type_name(), "list");

Hashability

Only immutable variants (None, Ellipsis, Bool, Int, Float, String, Bytes) implement Hash. Attempting to hash mutable variants (List, Dict) will panic.

JSON Serialization

MontyObject supports JSON serialization with natural mappings: Bidirectional (can serialize and deserialize):
  • None ↔ JSON null
  • Bool ↔ JSON true/false
  • Int ↔ JSON integer
  • Float ↔ JSON float
  • String ↔ JSON string
  • List ↔ JSON array
  • Dict ↔ JSON object (keys must be strings)
Output-only (serialize only, cannot deserialize from JSON):
  • Ellipsis{"$ellipsis": true}
  • Tuple{"$tuple": [...]}
  • Bytes{"$bytes": [...]}
  • Exception{"$exception": {"type": "...", "arg": "..."}}
  • Repr{"$repr": "..."}

Build docs developers (and LLMs) love