Skip to content

Feature: pip-installable MDSplus "local" wheel - #3078

Draft
dgarnier wants to merge 1 commit into
MDSplus:alphafrom
dgarnier:python-local-wheel
Draft

Feature: pip-installable MDSplus "local" wheel#3078
dgarnier wants to merge 1 commit into
MDSplus:alphafrom
dgarnier:python-local-wheel

Conversation

@dgarnier

@dgarnier dgarnier commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

As promised in the discussion about #3074, I had an idea for a re-direct python wheel.
The idea is just build a wheel that does the minimum and make a .pth. Claude and
I got together and got a little more clever than that, so we don't need to run python
packaging tools during the build.

An optional build step (ENABLE_PYTHON_LOCAL_WHEEL, default on, easy to turn
off) that writes a small MDSplus wheel into <prefix>/python/wheelhouse. The
wheel is a redirect, not a copy: its only payload is a MDSplus.pth that adds
this install's python/MDSplus to a Python environment.

This is a nice-to-have, not a need-to-have. The usual PYTHONPATH=$MDSPLUS_DIR/python
works fine for most uses. This method adds some other niceties.

  • pip install MDSplus --find-links $MDSPLUS_DIR/python/wheelhouse into a venv pulls in numpy automatically, which a bare
    PYTHONPATH does not;
  • another project can list MDSplus as a dependency and resolve it from the
    wheelhouse (pip/uv --find-links) rather than wiring PYTHONPATH in each
    project or CI job.

Kept deliberately small and self-contained so it's cheap to maintain or ignore:
one python/local_wheel/ subdir, a stdlib-only make_wheel.py (no build
backend, no network), and the .pth/bootstrap. Nothing else depends on it, and
it's behind a flag. Metadata and dependencies are copied from
python/MDSplus/pyproject.toml so pip show reports the real package.

Behavior of the redirect at runtime:

  • startup stays minimal — set MDSPLUS_DIR to the install the wheel was built
    for (or $MDSPLUS_DIR if it was relocated) and prepend its python/ to
    sys.path;
  • on the first import MDSplus, if needed, a one-shot hook sources that
    install's setup.sh to populate the environment (handy for pointing a
    throwaway venv at a specific build when testing);
  • it never spawns anything at plain startup, is wrapped so it can't break the
    interpreter, and MDSPLUS_LOCAL_WHEEL_DISABLE=1 disables it.

Draft while it gets more testing. See python/local_wheel/README.md for usage.

@dgarnier dgarnier added feature Indicates new feature requests or implementations build Relates to the build system packaging Relates to packaging and distribution api/python Relates to the Python API labels Jul 26, 2026
@dgarnier
dgarnier force-pushed the python-local-wheel branch from 581164b to 892608b Compare July 26, 2026 09:58
Build a small MDSplus wheel, at install time, into <prefix>/python/wheelhouse.
Its only payload is a MDSplus.pth (+ a _mdsplus_bootstrap.py it imports) that
points a Python environment at this install's python/MDSplus package -- a
redirect, not a copy. Gated behind ENABLE_PYTHON_LOCAL_WHEEL (default ON).

Why a wheel instead of PYTHONPATH=$MDSPLUS_DIR/python: setting PYTHONPATH makes
`import MDSplus` work but leaves the environment with no record that MDSplus is
installed. Shipping it as a real distribution means:
  - MDSplus's dependencies (numpy, ...) are pulled in automatically by the
    resolver instead of being wrangled out of band;
  - it installs into a venv / uv-managed env and just works;
  - other pyprojects can depend on `MDSplus` and resolve it from the local
    wheelhouse (pip/uv --find-links, or a flat uv index) -- no per-project or
    per-CI PYTHONPATH plumbing;
  - being a redirect, it always imports the MDSplus that matches the installed
    C libraries.

At import time the bootstrap back-determines MDSPLUS_DIR from the install the
wheel was built for and sets up its environment -- convenient for testing:
  - startup is minimal: set MDSPLUS_DIR to the baked install (or $MDSPLUS_DIR
    if it was relocated) and prepend its python/ to sys.path;
  - on the first `import MDSplus`, if MDSPLUS_DIR was rewritten or the env is
    not sourced, a one-shot import hook sources the install's setup.sh (honoring
    local envsyms) and merges the resulting environment;
  - it never spawns a process at plain startup and can never break the
    interpreter; MDSPLUS_LOCAL_WHEEL_DISABLE=1 turns it off.

The wheel is assembled by make_wheel.py using only the standard library (no
build backend, no pip build isolation, no network); its dependencies and
metadata are copied from python/MDSplus/pyproject.toml so tooling reports the
genuine package info.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dgarnier
dgarnier force-pushed the python-local-wheel branch from 892608b to d1ed40d Compare July 27, 2026 12:08
github-actions Bot pushed a commit to dgarnier/homebrew-plasma that referenced this pull request Jul 27, 2026
Carry the python-local-wheel feature (MDSplus/mdsplus#3078) as a patch:
a redirect wheel is built into <prefix>/python/wheelhouse at install
time (ENABLE_PYTHON_LOCAL_WHEEL), replacing the formula-built copy
wheel, so venv/uv environments can `pip install --find-links` it.

Test block: pin the venv to brewed python@3.13 (a uv-managed python3.13
earlier on PATH ships a pip too old for Homebrew's release-cooldown
--uploaded-prior-to=P1D flag), assert the .pth redirect actually
installs, and only exact-match the version on stable builds (Homebrew's
HEAD-<sha> label never equals MDSplus's release tag).

Revision bump so existing installs pick up the wheelhouse.

Closes #34.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Darren Garnier <dgarnier@reinrag.net>
@dgarnier

Copy link
Copy Markdown
Contributor Author

Testing this patch with homebrew here:

https://github.com/dgarnier/homebrew-plasma/releases/tag/mdsplus-alpha_release-7-160-2_1

can install on macOS with:

brew install dgarnier/plasma/mdsplus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api/python Relates to the Python API build Relates to the build system feature Indicates new feature requests or implementations packaging Relates to packaging and distribution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant