Skip to content

fix: resolve relative path sources in --sandbox uv export#9052

Open
VishakBaddur wants to merge 4 commits intomarimo-team:mainfrom
VishakBaddur:fix/sandbox-relative-path-sources
Open

fix: resolve relative path sources in --sandbox uv export#9052
VishakBaddur wants to merge 4 commits intomarimo-team:mainfrom
VishakBaddur:fix/sandbox-relative-path-sources

Conversation

@VishakBaddur
Copy link
Copy Markdown
Contributor

Fixes #8980

Problem

marimo edit --sandbox fails when a script's inline metadata uses relative path sources in [tool.uv.sources]. uv export --script returns paths relative to the script file, but those lines get written to a temp requirements file. When uv run --with-requirements processes that file, it resolves paths relative to CWD - not the script's directory - causing path resolution failures.

Fix

In _uv_export_script_requirements_txt (marimo/_cli/sandbox.py), convert any relative paths (.-prefixed) to absolute paths using the script's parent directory as the base. Handles both editable (-e ../../) and non-editable (../../) path sources. Non-path deps and already-absolute paths are left unchanged.

Test

Added test_uv_export_script_requirements_txt_resolves_relative_paths covering:

  • Editable relative paths (-e ../../) → resolved to absolute
  • Non-editable relative paths (../other_pkg) → resolved to absolute
  • Regular deps (numpy==1.26.0) → unchanged
  • Already-absolute paths → unchanged

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 5, 2026

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

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Apr 9, 2026 3:03pm

Request Review

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 5, 2026

Bundle Report

Changes will increase total bundle size by 4.44kB (0.02%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
marimo-esm 24.83MB 4.44kB (0.02%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: marimo-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/cells-*.js 143 bytes 703.0kB 0.02%
assets/index-*.js 1.5kB 601.53kB 0.25%
assets/edit-*.js 641 bytes 371.97kB 0.17%
assets/index-*.css 67 bytes 362.06kB 0.02%
assets/dist-*.js -46 bytes 137 bytes -25.14%
assets/dist-*.js -35 bytes 102 bytes -25.55%
assets/dist-*.js 87 bytes 256 bytes 51.48% ⚠️
assets/dist-*.js 46 bytes 183 bytes 33.58% ⚠️
assets/dist-*.js 107 bytes 276 bytes 63.31% ⚠️
assets/dist-*.js 73 bytes 177 bytes 70.19% ⚠️
assets/dist-*.js -1 bytes 176 bytes -0.56%
assets/dist-*.js 159 bytes 335 bytes 90.34% ⚠️
assets/dist-*.js -92 bytes 164 bytes -35.94%
assets/dist-*.js -234 bytes 169 bytes -58.06%
assets/dist-*.js 58 bytes 160 bytes 56.86% ⚠️
assets/dist-*.js 144 bytes 403 bytes 55.6% ⚠️
assets/dist-*.js 5 bytes 169 bytes 3.05%
assets/dist-*.js -172 bytes 104 bytes -62.32%
assets/dist-*.js 204 bytes 387 bytes 111.48% ⚠️
assets/dist-*.js 155 bytes 259 bytes 149.04% ⚠️
assets/dist-*.js 33 bytes 137 bytes 31.73% ⚠️
assets/dist-*.js -283 bytes 104 bytes -73.13%
assets/dist-*.js -152 bytes 183 bytes -45.37%
assets/dist-*.js -56 bytes 104 bytes -35.0%
assets/JsonOutput-*.js 1.06kB 336.29kB 0.32%
assets/ai-*.js 552 bytes 249.82kB 0.22%
assets/add-*.js 16 bytes 192.75kB 0.01%
assets/cell-*.js 95 bytes 182.9kB 0.05%
assets/layout-*.js -6 bytes 129.66kB -0.0%
assets/input-*.js 4 bytes 60.43kB 0.01%
assets/panels-*.js 2 bytes 48.51kB 0.0%
assets/file-*.js 233 bytes 47.03kB 0.5%
assets/file-*.js (Deleted) -349 bytes 0 bytes -100.0% 🗑️
assets/useNotebookActions-*.js 31 bytes 27.68kB 0.11%
assets/react-*.browser.esm-BUNcfKXO.js (New) 25.64kB 25.64kB 100.0% 🚀
assets/session-*.js 3 bytes 25.0kB 0.01%
assets/vega-*.browser-DXARUlxo.js (New) 24.8kB 24.8kB 100.0% 🚀
assets/MarimoErrorOutput-*.js 19 bytes 24.0kB 0.08%
assets/usePress-*.js 1 bytes 20.73kB 0.0%
assets/RSPContexts-*.js (New) 18.23kB 18.23kB 100.0% 🚀
assets/app-*.js -3 bytes 11.43kB -0.03%
assets/react-*.esm-BUYTQ32a.js (New) 8.37kB 8.37kB 100.0% 🚀
assets/useBoolean-*.js -3 bytes 5.77kB -0.05%
assets/config-*.js 320 bytes 5.47kB 6.21% ⚠️
assets/emotion-*.esm-DYxi7n2b.js (New) 4.37kB 4.37kB 100.0% 🚀
assets/button-*.js 93 bytes 3.93kB 2.43%
assets/mermaid-*.core-CvPV98yl.js (New) 2.38kB 2.38kB 100.0% 🚀
assets/useAsyncData-*.js 22 bytes 2.07kB 1.08%
assets/react-*.browser.esm-D0qmuH5W.js (Deleted) -25.64kB 0 bytes -100.0% 🗑️
assets/vega-*.browser-CRZ52CKf.js (Deleted) -24.8kB 0 bytes -100.0% 🗑️
assets/VisuallyHidden-*.js (Deleted) -18.23kB 0 bytes -100.0% 🗑️
assets/react-*.esm-B8rtE4cC.js (Deleted) -8.37kB 0 bytes -100.0% 🗑️
assets/emotion-*.esm-DD4AwVTU.js (Deleted) -4.37kB 0 bytes -100.0% 🗑️
assets/mermaid-*.core-D6xRJ9xD.js (Deleted) -2.38kB 0 bytes -100.0% 🗑️

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes sandbox failures when uv export --script emits relative local path requirements by rewriting those paths to be absolute based on the script’s directory before writing the temp requirements file used by uv run --with-requirements.

Changes:

  • Resolve .-prefixed path requirement lines from uv export --script into absolute paths in the sandbox CLI.
  • Add a regression test covering editable and non-editable relative path lines as well as unchanged “normal” and already-absolute deps.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
marimo/_cli/sandbox.py Converts relative path lines from uv export --script output to absolute paths rooted at the script directory.
tests/_cli/test_sandbox.py Adds a unit test to ensure relative paths in exported requirements are resolved correctly.

Comment thread marimo/_cli/sandbox.py
Comment on lines +215 to +219
editable = line.startswith("-e ")
path = line[3:].strip() if editable else line.strip()
if path.startswith("."):
path = str((script_dir / path).resolve())
prefix = "-e " if editable else ""
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

Current parsing treats the entire line (minus optional "-e ") as a filesystem path. If a requirements line contains an environment marker ("; ...") or an inline comment, e.g. "../pkg ; python_version<'3.12'" or "../pkg # comment", this code will resolve the marker/comment as part of the path and emit an invalid requirement. Consider splitting the line into a path token + remainder (markers/comments), resolving only the path token, then re-attaching the untouched remainder (and similarly for editable lines).

Copilot uses AI. Check for mistakes.
Comment thread tests/_cli/test_sandbox.py Outdated
"-e ../../\n../other_pkg\nnumpy==1.26.0\n/absolute/path\n\n"
)

with patch("subprocess.run", return_value=mock_result):
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

This test patches the global "subprocess.run" symbol. To avoid affecting other code that might call subprocess during the patch context (and to be consistent with other tests in this file), patch the call site instead ("marimo._cli.sandbox.subprocess.run").

Suggested change
with patch("subprocess.run", return_value=mock_result):
with patch("marimo._cli.sandbox.subprocess.run", return_value=mock_result):

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread marimo/_cli/sandbox.py
Comment on lines +217 to +223
# Split off any environment markers ("; ...") or inline comments ("# ...")
# so we only resolve the path token itself.
for sep in (" ;", " #"):
if sep in rest:
path_token, remainder = rest.split(sep, 1)
remainder = sep.lstrip() + remainder
break
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The separator handling for environment markers / inline comments strips the leading whitespace (sep.lstrip()), so a line like ../pkg # comment would be reconstructed as /abs/path#comment (no whitespace), which is no longer an inline comment in requirements parsing and can change semantics (e.g., treated as a URL fragment). Consider preserving the original separator (keep the space before #/;) and also handling markers that may appear without a preceding space (e.g., ;python_version<...).

Suggested change
# Split off any environment markers ("; ...") or inline comments ("# ...")
# so we only resolve the path token itself.
for sep in (" ;", " #"):
if sep in rest:
path_token, remainder = rest.split(sep, 1)
remainder = sep.lstrip() + remainder
break
# Split off any environment markers ("; ...") or inline comments
# ("# ...") so we only resolve the path token itself.
#
# Preserve the original separator exactly as written. This avoids
# turning `../pkg # comment` into `/abs/path# comment`, which changes
# requirements parsing semantics. Environment markers may also appear
# without a leading space, e.g. `../pkg;python_version<"3.12"`.
marker_idx = rest.find(";")
comment_idx = -1
for i, char in enumerate(rest):
if char == "#" and i > 0 and rest[i - 1].isspace():
comment_idx = i
break
split_points = [idx for idx in (marker_idx, comment_idx) if idx != -1]
if split_points:
split_idx = min(split_points)
path_token = rest[:split_idx]
remainder = rest[split_idx:]

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

--sandbox fails for scripts with relative path sources in [tool.uv.sources]

2 participants