Skip to content

fix: use hatch's default env so the uv installer is inherited#4023

Open
lhoupert wants to merge 4 commits into
zarr-developers:mainfrom
lhoupert:fix/hatch-default-env-installer-typo
Open

fix: use hatch's default env so the uv installer is inherited#4023
lhoupert wants to merge 4 commits into
zarr-developers:mainfrom
lhoupert:fix/hatch-default-env-installer-typo

Conversation

@lhoupert
Copy link
Copy Markdown

@lhoupert lhoupert commented Jun 1, 2026

Summary

[tool.hatch.envs.defaults] (plural) was a typo. Hatch's inherited base environment is default (singular), so the intended installer = "uv" was never applied to any environment — test, docs, etc. silently used the default virtualenv/pip backend. This renames it to default, plus the CI changes required for the now-active uv installer to work.

Changes

  • pyproject.toml: [tool.hatch.envs.defaults][tool.hatch.envs.default]
  • .github/workflows/{test,gpu_test,hypothesis}.yml: add astral-sh/setup-uv and set HATCH_ENV_TYPE_VIRTUAL_UV_PATH=uv so hatch uses that uv directly instead of bootstrapping its own
  • .github/workflows/test.yml: install hatch via pip install hatch==1.16.5 (as docs/contributing.md prescribes) instead of the pypa/hatch (pyapp) action

Why the CI changes are needed

Activating the uv installer for the first time means hatch needs a uv binary, which CI never provided. On Linux, setup-uv + the explicit uv path is enough. On macOS, hatch's pyapp (standalone) build ships a pip whose shebang points at a non-existent python3.12; with the uv installer active hatch invokes it and fails (exit 126). Installing hatch via pip runs it on the runner's normal Python with a working pip on every OS. .python-version is not involved.

Verification

All CI green across the full matrix (macOS / Ubuntu / Windows × Python 3.12 / 3.13 / 3.14 × optional / minimal), plus GPU, Slow Hypothesis, doctests, docs, lint, wheels, codecov.

Note for reviewers

The default rename applies installer = "uv" to every hatch environment. That's the evident original intent, but it's the behavioral change worth a conscious sign-off.

Closes #4022.

`[tool.hatch.envs.defaults]` (plural) is a standalone environment that
nothing inherits from — hatch's base environment is `default` (singular).
As written, `installer = "uv"` never applied to `test`, `docs`, etc., so
those envs fell back to the `virtualenv` backend.

This breaks contributors whose Python is uv-managed: hatch hands the
`~/.local/bin/pythonX.Y` symlink to virtualenv, which mis-relocates the
python-build-standalone interpreter (`sys.base_prefix = '/install'`,
`ModuleNotFoundError: No module named 'encodings'`). Creating the env with
`uv venv` relocates it correctly.

Renaming to `default` makes the intended uv installer apply to all envs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added the needs release notes Automatically applied to PRs which haven't added release notes label Jun 1, 2026
@chuckwondo
Copy link
Copy Markdown
Contributor

Good catch!

@chuckwondo
Copy link
Copy Markdown
Contributor

I think that is somehow not interacting well with the .python-version file that specifies 3.12. The 3.14 tests fail, complaining about not finding python 3.12: https://github.com/zarr-developers/zarr-python/actions/runs/26764075490/job/78885436763?pr=4023

Activating `installer = "uv"` (via the `default` env fix) means hatch now
needs a uv binary to create/sync the test, gputest and hypothesis envs.
These workflows install hatch via the `pypa/hatch` action (a pyapp build
with its own bundled Python) but never set up uv, so hatch fell back to
provisioning uv through its pyapp runtime — whose `pip` has a `python3.12`
shebang that doesn't exist on non-3.12 runners:

    .../pyapp/hatch/.../python/bin/python3.12: No such file or directory
    Process completed with exit code 126

Add the repo's standard `astral-sh/setup-uv` step (already used by docs/lint
workflows) before "Install Hatch" so hatch finds uv on PATH and uses it
directly. With uv available, `uv venv --python <matrix>` selects the correct
interpreter, so the root `.python-version` (3.12, for the dev env) no longer
interferes with the 3.13/3.14 matrix envs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lhoupert
Copy link
Copy Markdown
Author

lhoupert commented Jun 1, 2026

Thanks @chuckwondo. I will dug into this

lhoupert and others added 2 commits June 1, 2026 21:51
Installing uv on PATH is not enough: hatch only skips provisioning its
internal `hatch-uv` env when an explicit uv path is set. Otherwise it
bootstraps uv via its bundled pyapp `pip` (shebang `python3.12`), which
fails on non-3.12 runners with exit code 126.

Set `HATCH_ENV_TYPE_VIRTUAL_UV_PATH=uv` so hatch uses the uv provided by
astral-sh/setup-uv directly instead of bootstrapping. Verified locally:
with the explicit path set, `hatch env create` succeeds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The macOS jobs failed even with uv on PATH: hatch's pyapp (standalone)
build on macOS has a `pip` whose shebang points at a non-existent
`python3.12`, and activating the uv installer makes hatch invoke it
(`exit code 126`). Linux pyapp builds are unaffected, which is why the
GPU and Hypothesis (Linux) workflows pass.

Install hatch with `python -m pip install hatch==1.16.5` (the method the
contributing docs already document) so hatch runs on the runner's normal
Python with a working pip on every OS. uv (from setup-uv) is still used as
the env installer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@d-v-b
Copy link
Copy Markdown
Contributor

d-v-b commented Jun 1, 2026

is there an issue tracking this behavior over in the hatch issue tracker?

@lhoupert
Copy link
Copy Markdown
Author

lhoupert commented Jun 1, 2026

where is this issue tracker?

@lhoupert
Copy link
Copy Markdown
Author

lhoupert commented Jun 1, 2026

Claude's Investigation summary

Root cause: [tool.hatch.envs.defaults] (plural) isn't a hatch concept — the inherited base env is default (singular) — so installer = "uv" was never applied to any env. Fixing the typo activates uv for the first time, which surfaced two CI gaps:

  1. uv was never set up in CI. The hatch-based workflows install hatch via the pypa/hatch action and never provide uv, so with the installer active hatch tried to bootstrap uv itself and failed. Fixed by adding astral-sh/setup-uv and HATCH_ENV_TYPE_VIRTUAL_UV_PATH=uv — this cleared the Linux jobs (GPU, Hypothesis).

  2. macOS pyapp hatch has a broken pip. Hatch's standalone build on macOS ships a pip whose shebang points at a non-existent python3.12; activating uv made hatch invoke it (exit 126). Linux is unaffected. Fixed by installing hatch via pip install hatch==1.16.5 in test.yml.

.python-version turned out not to be involved (the failing binary was hatch's runtime pip, not the env interpreter).

All CI is now green (full matrix + GPU + Hypothesis). Heads-up that the default rename applies installer = "uv" to every env — the evident intent, but worth a conscious 👍.

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

Labels

needs release notes Automatically applied to PRs which haven't added release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[tool.hatch.envs.defaults] is likely a typo for defaultinstaller = "uv" never applies

3 participants