WASM: version specifiers in a notebook's PEP 723 dependencies are dropped before install
Describe the bug
In a WASM notebook, a pinned dependency is installed unpinned.
PyodideSession.find_packages reads the notebook's PEP 723 block and then strips each requirement before handing it to micropip:
# marimo/_pyodide/pyodide_session.py
if len(script_deps) > 0:
return [strip_requirement_name(dep) for dep in script_deps]
>>> deps = ["pandas==2.1.0", "nltools==0.6.0.dev2"]
>>> [strip_requirement_name(d) for d in deps]
['pandas', 'nltools']
So micropip.install never sees the constraint the notebook declared.
Why this is more than a loss of precision
Installers skip pre-releases unless a specifier asks for one. A pin is therefore the only thing that can select a pre-release — so stripping it doesn't make the resolution fuzzier, it sends it to a different release, and specifically to the newest stable one.
That is exactly the case that broke for us. The notebook pinned nltools==0.6.0.dev2, which installs and runs in Pyodide. Unpinned, nltools resolves to the latest stable, 0.5.1, which requires numpy<1.24:
await micropip.install("nltools==0.6.0.dev2") # ok
await micropip.install("nltools") # Can't find a pure Python 3 wheel for 'numpy<1.24'
The reader gets Some packages failed to install → Failed to install nltools, and the notebook cannot boot.
Reproduce
A notebook whose block pins a package whose newest stable release is unusable in Pyodide, while a pre-release works:
# /// script
# dependencies = ["nltools==0.6.0.dev2"]
# ///
import marimo
app = marimo.App()
@app.cell
def _():
from nltools.data import BrainData
return
Open it in WASM. The install fails; the browser console shows the numpy<1.24 resolution error from the 0.5.1 metadata.
Expected
micropip receives nltools==0.6.0.dev2 — the requirement the notebook declared.
Notes
The stripped list is used in three places in loadNotebookDeps (frontend/src/core/wasm/worker/bootstrap.ts). Two are "already installed?" lookups keyed by name; only the third, micropip.install, wants the requirement. So the name can be derived where a name is needed, leaving the requirement intact for the install — the existing skip behaviour is unchanged and only what gets installed differs.
Happy to send a PR along these lines.
Environment
marimo 0.24.2, Pyodide v314.0.0, Chrome. Found while giving chapters an in-browser editor in marimo-book.
Source: marimo-team/marimo