Skip to content

Centralize uv and PEP 723 operations - #10695

Open
manzt wants to merge 3 commits into
mainfrom
sandbox-envs
Open

Centralize uv and PEP 723 operations#10695
manzt wants to merge 3 commits into
mainfrom
sandbox-envs

Conversation

@manzt

@manzt manzt commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

marimo invoked uv and edited PEP 723 metadata from several code paths. CLI sandboxing, exports, converters, file management, and package installation each carried part of that logic, so working directories, error handling, and serialization could drift.

This PR gives those operations two owners:

uv(["add", "--script", path, "numpy"], cwd=notebook_dir)
uv_stream(["sync", "--script", path], on_output, cwd=notebook_dir)

script_metadata.add_dependencies(path, ["numpy"])
script_metadata.ensure_marimo(path)
project = script_metadata.loads(code)

marimo._environments.uv owns executable discovery, invocation, and errors. marimo._environments.script_metadata owns reading and writing PEP 723 blocks. Existing callers now use these modules instead of constructing subprocess commands or rewriting metadata themselves.

For Markdown and Quarto notebooks, metadata edits use a short-lived Python carrier beside the notebook. This lets uv resolve relative paths and directory configuration from the notebook directory while preserving the surrounding document.

This PR does not change how sandbox processes are launched. It establishes the command and metadata operations used by the rest of the stack.

@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
marimo-docs Ready Ready Preview Sep 4, 2026 4:03pm UTC

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@manzt manzt added the bug Something isn't working label Aug 28, 2026
@manzt manzt changed the title sandbox envs Launch sandboxes from script environments Aug 28, 2026
@manzt
manzt marked this pull request as ready for review August 29, 2026 18:41
Copilot AI lite review requested due to automatic review settings August 29, 2026 18:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@dmadisetti
dmadisetti self-requested a review August 31, 2026 20:11
@manzt manzt changed the title Launch sandboxes from script environments Centralize uv and PEP 723 operations Sep 2, 2026
@manzt manzt added the test-all flag to run all tests in a PR label Sep 2, 2026
marimo shells out to uv from several modules, each with its own
subprocess idiom, availability check, and stderr handling. Failures
either escape as bare CalledProcessError or are silently swallowed.

These changes add `marimo._environments.uv` as the single way to invoke
uv with captured output. A nonzero exit raises a typed error,
classified once from stderr, that callers recover on.

```py
try:
    uv(["export", "--script", name])
except UvMissingScriptMetadataError:
    ...  # script has no PEP 723 block yet
```

Streaming package installs keep their existing path.
marimo writes script metadata blocks in several different code paths with
separate serialization strategies.

- `uv add --script` edits it in the package manager
- `tomlkit` re-serialization edits it in scripts.py
- regex splices that serialization entirely

These changes add `marimo._environments.script_metadata` as the single
reader and writer. In-place edits of a user file delegate to uv so
formatting survives, while whole-block generation for converters, codegen,
and export serializes with tomlkit, so the lossy fallback is gone.

```py
script_metadata.add_dependencies(path, ["numpy"])
script_metadata.ensure_marimo(path)
project = script_metadata.loads(code)
code = script_metadata.replace_block(code, script_metadata.dumps(project))
```

Metadata edit verbs normalize missing-tool, command, timeout, and
filesystem failures as `ScriptMetadataError`. Callers such as the package
manager can therefore preserve their boolean failure contract without
knowing how uv was invoked.

Markdown and qmd notebooks round-trip their frontmatter header verbatim
through a carrier, a hidden sidecar next to the notebook
(`.marimo-v1-<name>.py`), so uv anchors relative paths in the metadata
against the notebook's directory. The versioned, deterministic name marks
the file as marimo's; a carrier exists only while uv runs, and every edit
first sweeps strays a killed process may have left. The document is only
rewritten when the edit succeeds. `PyProjectReader` remains the read-only
view over the parsed block.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working test-all flag to run all tests in a PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants