From 8881b25f980aa2bf4298720442a62a117540e37a Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Thu, 13 Aug 2026 12:10:17 +0200 Subject: [PATCH 1/2] fix(build): use an sdist allowlist so the zarr sdist stops shipping subpackages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The root sdist config was a blocklist naming /.github, /bench and /docs, so every release shipped whatever else happened to sit in the repository root. That included the whole packages/ tree — the zarr-indexing, zarr-metadata and zarr-http-server sources, which are released as their own distributions — plus ci/, design/, towncrier fragments and other repo furniture. 2.9M of the 1.4M sdist was other people's packages. Replace it with an explicit allowlist, matching what packages/zarr-indexing and packages/zarr-metadata already do. Including /docs also fixes a second problem: tests/test_docs.py walks docs/ and testpaths collects docs/user-guide, so with docs/ excluded the shipped test suite died at collection with 'Not a file or directory'. tests/test_docs.py now runs green from an unpacked sdist (61 passed, 2 skipped), and full collection finds 7581 tests with no errors. Assisted-by: ClaudeCode:claude-opus-5 --- changes/4261.misc.md | 1 + pyproject.toml | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 changes/4261.misc.md diff --git a/changes/4261.misc.md b/changes/4261.misc.md new file mode 100644 index 0000000000..ca2a3fbb1e --- /dev/null +++ b/changes/4261.misc.md @@ -0,0 +1 @@ +The contents of the `zarr` source distribution are now defined by an explicit allowlist rather than a blocklist. Previously the sdist bundled the whole `packages/` tree — `zarr-indexing`, `zarr-metadata` and `zarr-http-server`, which are released as their own distributions — along with CI configuration and other repository files. The sdist also now ships `docs/`, so the test suite it carries can be collected and run from an unpacked sdist. diff --git a/pyproject.toml b/pyproject.toml index e0fbfc08fc..58e0383a18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,11 +2,27 @@ requires = ["hatchling>=1.29.0", "hatch-vcs"] build-backend = "hatchling.build" +# An allowlist, so nothing that merely happens to sit in the repository root can +# ride along in a release. The blocklist this replaces named three directories +# and so shipped everything else, including the entire `packages/` tree — the +# zarr-indexing, zarr-metadata and zarr-http-server sources, each of which is +# released separately — inside every `zarr` sdist, plus `ci/`, `design/`, +# towncrier fragments and assorted repo furniture. The list keeps the sdist +# self-testing: +# `tests/test_docs.py` walks `docs/` and executes every python block it finds, +# `testpaths` collects `docs/user-guide`, and the pages under +# `docs/user-guide/examples/` pull their source out of `examples/` with pymdownx +# snippet includes. `mkdocs.yml` and `mkdocs_hooks.py` come along so `mkdocs +# build` also runs from an unpacked sdist. `pyproject.toml`, `README.md` and +# `LICENSE.txt` are added by hatchling itself. [tool.hatch.build.targets.sdist] -exclude = [ - "/.github", - "/bench", +include = [ + "/src", + "/tests", "/docs", + "/examples", + "/mkdocs.yml", + "/mkdocs_hooks.py", ] [project] From 0573aaee96363a7404e3bdf56218a96f76b4b5a2 Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Thu, 13 Aug 2026 16:13:45 +0200 Subject: [PATCH 2/2] docs(build): trim the sdist allowlist comment Drop the narration of the blocklist this replaced -- that history lives in git -- and keep only the durable rationale and the reason each entry is on the list. Assisted-by: ClaudeCode:claude-opus-5 --- pyproject.toml | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 58e0383a18..5e8129a6a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,19 +2,15 @@ requires = ["hatchling>=1.29.0", "hatch-vcs"] build-backend = "hatchling.build" -# An allowlist, so nothing that merely happens to sit in the repository root can -# ride along in a release. The blocklist this replaces named three directories -# and so shipped everything else, including the entire `packages/` tree — the -# zarr-indexing, zarr-metadata and zarr-http-server sources, each of which is -# released separately — inside every `zarr` sdist, plus `ci/`, `design/`, -# towncrier fragments and assorted repo furniture. The list keeps the sdist -# self-testing: -# `tests/test_docs.py` walks `docs/` and executes every python block it finds, -# `testpaths` collects `docs/user-guide`, and the pages under -# `docs/user-guide/examples/` pull their source out of `examples/` with pymdownx -# snippet includes. `mkdocs.yml` and `mkdocs_hooks.py` come along so `mkdocs -# build` also runs from an unpacked sdist. `pyproject.toml`, `README.md` and -# `LICENSE.txt` are added by hatchling itself. +# An allowlist, not a blocklist: anything new — a subpackage under `packages/`, a +# config file in the repository root — stays out of the sdist unless it is named +# here. Beyond `src` and `tests`, the entries are what keeps the shipped test +# suite and docs build runnable from an unpacked sdist: `tests/test_docs.py` +# walks `docs/` and `testpaths` collects `docs/user-guide`; the pages under +# `docs/user-guide/examples/` pull their source out of `examples/` via pymdownx +# snippet includes; `mkdocs.yml` and `mkdocs_hooks.py` let `mkdocs build` run +# too. `pyproject.toml`, `README.md`, `LICENSE.txt` and `.gitignore` are added by +# hatchling itself. [tool.hatch.build.targets.sdist] include = [ "/src",