os module: host-mediated process & identity calls (system, uname, getcwd, cpu_count, getpid)
Five os functions would follow the exact pattern os.getenv/os.environ already use: the sandbox suspends with a typed OsFunctionCall, and the host decides what the answer is.
| Function | Host answer |
|---|---|
os.system(command) |
the exit-status int the sandbox should observe |
os.uname() |
a 5-field named tuple (sysname, nodename, release, version, machine) |
os.getcwd() |
a str |
os.cpu_count() / os.getpid() |
ints |
Why: monty's documented os subset omits the process/identity family entirely (limitations/os.md lists os.system, os.getcwd, os.uname, os.cpu_count, os.getpid under not-implemented), so import os; os.system("ls") dies with AttributeError before any host policy can apply — while the neighboring filesystem calls (listdir, stat, environ) are already host-mediated os-calls. There's no host-side alternative: external_lookup resolves undefined names, not module attributes, and the sandbox's os module is compiled into the worker binary.
Security: unchanged. The interpreter performs zero I/O — os.system hands the command string to the host and nothing is ever executed by monty itself; that's the same trust model as Path.write_text. With no handler, the standard no-handler error applies (current behavior is unchanged for anyone who opts out).
Details:
- CPython-exact error wording, including the
posix.prefix quirk (posix.uname() takes no arguments (1 given)) — dual-run test cases os.uname()returns a named tuple with attribute + index access; repr divergence (uname_result(...)vsposix.uname_result(...)) matches the existingStatResult(...)precedentos.systemaccepts str/bytes/PathLike like CPython (bytes decode lossily; documented)- additive
OsCalloneof arms (proto tags 25–29); snapshots stay compatible, no dump-version bump
Happy to send the PR.
Source: pydantic/monty