Summary
The current pydantic_monty docs/comments around mount= + os= are inconsistent.
Some code comments and test docs describe os= as a fallback for non-filesystem OS operations when mounts are configured, but the runtime intentionally also routes filesystem operations for unmounted paths into os=.
I think this should be documented clearly because it is easy for an embedder to assume that mount= is a complete filesystem allowlist once mounts are configured.
Current behavior
The runtime intentionally falls through to os= for unmounted filesystem paths:
crates/monty-python/src/monty_cls.rs
handle_mount_os_call() says the mount table returns None for non-filesystem ops and for paths that don't match any mount
- it also has the comment:
Intentional: unmounted paths fall through to os=
crates/monty-python/src/repl.rs
- same behavior in
handle_repl_os_call()
So with something like:
Monty(code).run(mount=MountDir('/data', ...), os=my_callback)
Path('/other/file.txt').read_text() can still be sent to my_callback.
Misleading wording
These places currently describe os= more narrowly:
crates/monty-python/src/mount.rs
fallback: Option<Py<PyAny>> is documented as an optional callable for non-filesystem OS operations
from_run_args() documents os as a fallback for non-filesystem OS operations
crates/monty-python/tests/test_mount_table.py
- module docstring says mounts run with optional Python fallback for non-filesystem ops via
os=
- section header says
Fallback via os= for non-filesystem ops
The public stub is not explicitly wrong, but it is incomplete:
crates/monty-python/python/pydantic_monty/_monty.pyi
run(..., os=...) says os is an optional callback for OS calls, but does not explain the interaction with mount= or that unmounted filesystem ops also reach the callback
Why this matters
This looks like a documentation bug / embedding footgun, not necessarily a core sandbox bug.
A caller could reasonably read the current wording and assume:
- mounted paths are handled by
mount=
- non-filesystem ops are handled by
os=
- unmounted filesystem paths are denied
But the actual behavior is:
- mounted filesystem paths are handled by
mount=
- non-filesystem ops go to
os=
- unmounted filesystem paths also go to
os=
That difference feels important enough to document explicitly.
Suggested fix
- Update the misleading wording in
mount.rs and test_mount_table.py
- Add user-facing docs for
run(..., mount=..., os=...) / feed_run(..., mount=..., os=...) clarifying that os= also receives OS operations not handled by mounts, including filesystem operations on unmounted paths
- Consider adding a test that explicitly documents this behavior
Summary
The current
pydantic_montydocs/comments aroundmount=+os=are inconsistent.Some code comments and test docs describe
os=as a fallback for non-filesystem OS operations when mounts are configured, but the runtime intentionally also routes filesystem operations for unmounted paths intoos=.I think this should be documented clearly because it is easy for an embedder to assume that
mount=is a complete filesystem allowlist once mounts are configured.Current behavior
The runtime intentionally falls through to
os=for unmounted filesystem paths:crates/monty-python/src/monty_cls.rshandle_mount_os_call()says the mount table returnsNonefor non-filesystem ops and for paths that don't match any mountIntentional: unmounted paths fall through to os=crates/monty-python/src/repl.rshandle_repl_os_call()So with something like:
Path('/other/file.txt').read_text()can still be sent tomy_callback.Misleading wording
These places currently describe
os=more narrowly:crates/monty-python/src/mount.rsfallback: Option<Py<PyAny>>is documented as an optional callable for non-filesystem OS operationsfrom_run_args()documentsosas a fallback for non-filesystem OS operationscrates/monty-python/tests/test_mount_table.pyos=Fallback via os= for non-filesystem opsThe public stub is not explicitly wrong, but it is incomplete:
crates/monty-python/python/pydantic_monty/_monty.pyirun(..., os=...)saysosis an optional callback for OS calls, but does not explain the interaction withmount=or that unmounted filesystem ops also reach the callbackWhy this matters
This looks like a documentation bug / embedding footgun, not necessarily a core sandbox bug.
A caller could reasonably read the current wording and assume:
mount=os=But the actual behavior is:
mount=os=os=That difference feels important enough to document explicitly.
Suggested fix
mount.rsandtest_mount_table.pyrun(..., mount=..., os=...)/feed_run(..., mount=..., os=...)clarifying thatos=also receives OS operations not handled by mounts, including filesystem operations on unmounted paths