Skip to content

Consolidate dependencies into pyproject.toml; drop requirements*.txt#2205

Merged
rly merged 9 commits into
devfrom
consolidate-deps-pyproject
Jun 26, 2026
Merged

Consolidate dependencies into pyproject.toml; drop requirements*.txt#2205
rly merged 9 commits into
devfrom
consolidate-deps-pyproject

Conversation

@rly

@rly rly commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Motivation

Fixes #2204. Adopts the hdmf dependency-management pattern: all dependency declarations live in pyproject.toml, and the requirements*.txt files are removed.

Changes

  • pyproject.toml: added [project.optional-dependencies] (termset, zarr, stream, and an all aggregate) and PEP 735 [dependency-groups] (test, docs).
  • Removed requirements.txt, requirements-dev.txt, requirements-opt.txt, requirements-doc.txt, requirements-min.txt. Kept environment-ros3.yml (conda/ROS3 jobs).
  • tox.ini: rewritten to install via extras/dependency_groups; a single build env; upgraded/prerelease use pip install -U/-U --pre; minimum envs use uv pip install --resolution lowest-direct (replaces requirements-min.txt).
  • CI workflows: install only tox and run tox -e <env>; ros3/coverage/sphinx jobs now install via pip install --group <group> ".[all]". Converted the test matrices from -pinned to -upgraded and to the single build env.
  • .readthedocs.yaml: installs --group docs ".[all]".
  • Docs: updated install_developers.rst (pip install --group test -e ".[all]"), software_process.rst, make_a_release.rst, and the release PR template; removed the obsolete update_requirements.rst.
  • termset extra: capped linkml and linkml-runtime below 1.11. Those versions require click>=8.2, while dandi (a docs/gallery dependency) requires click<8.2. The gallery tox env installs the termset extra and the docs group in separate pip install -U transactions, so an uncapped termset transaction force-upgrades click to a version that breaks dandi, failing the pip check step. The cap keeps click at 8.1.x, which satisfies the whole stack.

Validation

  • pyproject.toml parses; optional-dependencies and dependency-groups resolve.
  • tox config resolves for all environment types (validated with tox config -e <env> using tox 4.55 + uv in an isolated venv). The minimum envs share hdmf's known tox config introspection quirk but run normally via tox -e.
  • All 11 workflow YAML files and .readthedocs.yaml validate.
  • The click cap was verified by reproducing the gallery env's two-stage pip install -U sequence (docs group, then termset extra): with both caps in place the stack resolves to click 8.1.8 and pip check passes.

Notes / needs CI

  • The full CI run is the real validation for the tox env matrices, the uv --resolution lowest-direct minimum builds, and the pip install --group commands (requires pip ≥ 25.1, present on the runners).
  • The test group drops black/isort (ruff supersedes them). Optional-dependency version floors mirror hdmf where applicable.
  • The linkml/linkml-runtime <1.11 cap is a workaround for an upstream click constraint disagreement between dandi and linkml. It can be lifted once dandi relaxes its click<8.2 bound or linkml regains click<8.2 compatibility.

🤖 Generated with Claude Code

Adopt the hdmf dependency-management pattern:
- Declare optional feature dependencies under [project.optional-dependencies]
  (termset, zarr, stream, all) and development dependencies under PEP 735
  [dependency-groups] (test, docs) in pyproject.toml.
- Remove requirements.txt, requirements-dev.txt, requirements-opt.txt,
  requirements-doc.txt, and requirements-min.txt. Keep environment-ros3.yml.
- Rewrite tox.ini to install deps via extras/dependency_groups, with a single
  build env and uv --resolution lowest-direct for minimum-version testing.
- Update CI workflows, .readthedocs.yaml, and developer docs to install via
  pyproject groups/extras (pip install --group ... ".[all]") instead of the
  requirements files. Convert the test matrices from -pinned to -upgraded.
- Remove the obsolete update_requirements doc.

Fixes #2204

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.29%. Comparing base (36cc7c3) to head (e460bf8).

Additional details and impacted files
@@           Coverage Diff           @@
##              dev    #2205   +/-   ##
=======================================
  Coverage   95.29%   95.29%           
=======================================
  Files          30       30           
  Lines        3038     3038           
  Branches      450      450           
=======================================
  Hits         2895     2895           
  Misses         87       87           
  Partials       56       56           
Flag Coverage Δ
integration 73.14% <ø> (ø)
unit 85.97% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

rly and others added 4 commits June 23, 2026 03:01
PyNWB did not previously expose pip extras, so drop the termset/zarr/stream/all
[project.optional-dependencies] added in the prior commit. The optional feature
dependencies now live in a dev-only `optional` dependency group (the former
requirements-opt.txt content); the `docs` group includes it so the gallery
examples still run. Update tox, CI, readthedocs, and docs to install via
`--group optional` / `--group docs` instead of the `.[all]` extra.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The gallery-py310-minimum tox env installs with `uv --resolution
lowest-direct`, which selected the oldest release on PyPI for every unpinned
dependency. For `lxml` that was `1.3.2` (a Python-2-era release) which fails
to build. Add lower bounds to the previously unbounded deps in the `optional`
and `docs` dependency groups (lxml>=4.9.3, Pillow>=10, hdf5plugin>=4,
pooch>=1.6, dataframe_image>=0.2.3, fsspec/requests/aiohttp/numcodecs) so the
minimum environments resolve to sensible, installable versions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The dependency-consolidation rewrite renamed/removed tox envs, so update the
release deploy workflow to use the test-py314-upgraded test env and the single
build env.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rly rly marked this pull request as ready for review June 23, 2026 18:17
rly and others added 2 commits June 23, 2026 11:22
The gallery-py310-minimum env applied `uv --resolution lowest-direct` to the
docs/optional dependency groups, dragging oaklib down to 0.5.12, which uses the
pydantic v1 `ModelMetaclass` API and fails to import against the pydantic v2
that gets resolved transitively.

Install the docs and optional dependencies at their latest compatible versions
first, then downgrade only pynwb's own direct dependencies to their minimum
versions. This matches the previous behavior, where gallery-minimum installed
requirements-min.txt (core, minimum) together with requirements-doc.txt
(optional/docs, latest).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add `[project.optional-dependencies]` extras `zarr` (hdmf-zarr, zarr,
numcodecs) and `termset` (linkml-runtime, schemasheets, oaklib) so users can
`pip install pynwb[zarr]` / `pip install pynwb[termset]`. The extras are the
single source for those feature dependencies.

Replace the dev-only `optional` dependency group with a `stream` group
(fsspec, requests, aiohttp) for the streaming tests; the docs group no longer
includes it. tox installs the feature deps via `extras` factors and the
gallery/optional/coverage/docs jobs install them with `".[zarr,termset]"`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rly rly mentioned this pull request Jun 25, 2026
13 tasks
linkml and linkml-runtime 1.11 require click>=8.2, while dandi (a docs/gallery
dependency) requires click<8.2. The gallery tox environment installs the termset
extra and the docs group in separate `pip install -U` transactions, so the
termset transaction force-upgrades click to 8.4.2 and breaks dandi, failing the
`pip check` step before the gallery examples run. Capping both packages keeps
click at 8.1.x, which satisfies every package in the stack.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rly

rly commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

The latest dandi and linkml-runtime cannot be installed together currently. dandi requires click <8.2.0 and linkml requires click >=8.2.0. There is an open ticket in dandi: dandi/dandi-cli#1631 and I opened a PR to remove the upper bound in dandi/dandi-cli#1883. Until that is resolved, we are limiting to linkml-runtime <1.11.0

@rly rly enabled auto-merge (squash) June 26, 2026 21:07
@rly rly merged commit 36097a3 into dev Jun 26, 2026
24 of 26 checks passed
@rly rly deleted the consolidate-deps-pyproject branch June 26, 2026 21:18
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.

Consolidate dependencies into pyproject.toml (optional-dependencies + dependency-groups), drop requirements*.txt

2 participants