Skip to content

Command Line

The monty binary runs Python files and gives you an interactive REPL, with the same sandbox, resource limits and type checking the libraries use. It is the fastest way to see what the interpreter does with a piece of code.

It ships with pydantic-monty (through the pydantic-monty-runtime dependency), or you can build it with cargo build -p monty-runtime.

$ monty -c "print('hello world')"
hello world

Usage

InvocationWhat it does
montyStart an interactive REPL
monty file.pyRun a Python file
monty -c "<code>"Run a program passed as a string, like python -c

Flags

FlagMeaning
-i, --interactiveRun the file or -c program, then drop into a REPL, like python -i
-t, --type-checkType check before executing
--type-check-formatDiagnostic format: full (default), concise, json, github and the other ty formats
-m, --mountMount a host directory into the sandbox (see below)
--max-durationMaximum execution time in seconds, e.g. 0.5
--max-memoryMaximum heap memory, e.g. 1024, 512KB, 10MB, 1GB
--max-recursion-depthMaximum call-stack depth; defaults to 1000 when any limit is set
--gc-intervalRun garbage collection every N allocations
--versionPrint the version

See resource limits for what the limits actually bound.

Mounts

-m /host/path::/virtual/path[::mode[::write_limit_bytes]]

The separator is :: rather than : so Windows drive letters stay unambiguous.

mode is ro (read-only, the default), rw (read-write) or overlay (in-memory overlay). write_limit_bytes is optional and applies to the write modes.

$ monty -m ./data::/data::ro -c "from pathlib import Path; print(Path('/data').iterdir())"

Without a mount, the sandbox has no filesystem at all. See filesystem access.

CLI mounts always use the default per-mount memory limit of 100 MB; there is no flag to change it.

Worker mode

monty subprocess runs the binary as a wire-protocol child: framed protobuf requests on stdin, framed events on stdout. This is how monty-pool — and through it the Python and JavaScript packages — runs Monty with crash isolation.

It is meant to be driven by a parent process, not by hand. Normal execution flags are rejected alongside it, because a subprocess worker reads all its configuration from the protocol.